⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.cpp

📁 简单的计算器程序
💻 CPP
字号:
#include<iostream>
#include<math.h>
#include <string>
#include <cstdlib>
#include<ctype.h>
using namespace std;
const int SIZE=20;
template <class T> class Queue;
template <class T> class SeqQueue;
enum ResultCode{Underflow,Overflow,Success,Duplicate,NotPresent,Inputwrong};
bool IsNumber(const char *s){
bool Numberdoor=0,Indexdoor=0,NePositivedoor=0;
bool Decimaldoor=0;
int i=0;
char c;
while(*(s+i)!='\0'){
	c=*(s+i);
	if(isdigit(c)) {
		Numberdoor=1;
		NePositivedoor=1;
	}
	else if(c=='.'){
		if(Decimaldoor==1)   return false;
		Numberdoor=0;
		Decimaldoor=1;
	}
	else if(c=='+'||c=='-'){
		if(NePositivedoor==1)   return false;
		if(Numberdoor==1)   return false;
		NePositivedoor=1;
		Numberdoor=0;

	}
	else if(c=='e'||c=='E'){
		if(Indexdoor==1)  return false;
		if(Numberdoor==0)   return false;
		Indexdoor=1;
		Numberdoor=0;
		NePositivedoor=0;
		Decimaldoor=1;
	}
	else return false;
	i++;
}
if(Numberdoor==0)   return false;
return true;
}
int icp(const char *c)
 {  // 计算运算符c的栈外优先级 
  int priority;
  switch(c[0]){
	case '(': priority=8; break;
	case ')': priority=1;break;
	case '+':  
	case '-': priority=2; break;
	case '*': 
	case '/': priority=4; break;
	case '^': priority=6; break;
	case '#': priority=0; break;
  }
  return priority;
 }
int isp(const char *c)
 {  // 计算运算符c的栈内优先级 
  int priority;
  switch(c[0]){
	case '(': priority=1; break;
	case ')': priority=8; break;
	case '+':  
	case '-': priority=3; break;
	case '*': 
	case '/': priority=5; break;
	case '^': priority=7; break;
	case '#': priority=0; break;
  }
  return priority;
 }
bool OperateSymbol(const char *c){
	switch(*c){
	case '+':
	case '-':
    case '*':
    case '^':
	case '(':
	case '/':
		     return true;
	default: return false;
	}
}
template <class T> 
class Queue
{
public:
	virtual bool IsEmpty()  const=0;
	virtual bool IsFull() const=0;
	virtual bool Front(T &x) const =0;
	virtual bool EnQueue(T x) =0;
	virtual bool DeQueue()=0;
	virtual bool Clear() =0;
};
template <class T>
class  SeqQueue:public Queue<T>
{
private:
	int front, rear;
	int maxSize;
	T *q;
public:
	SeqQueue(int mSize);
	~SeqQueue(){delete []q;}//释放内还
	bool IsEmpty() const{return front==rear;}
	bool IsFull() const {return (rear+1)% maxSize==front;}
	bool Front(T &x) const;
	bool EnQueue(T x);
	bool DeQueue();
	bool Clear() {front=rear=0; return true;}
	void ListAll();
	T IDfind(int i);
};
void  InfixToPostfix(SeqQueue<string> &suffix0);
template <class T>
SeqQueue<T>::SeqQueue(int mSize){
	maxSize=mSize;
	q=new T[maxSize];
	front=rear=0;
}
template <class T>
bool SeqQueue<T>::Front (T &x) const{
	if (IsEmpty()){
		cout<<"empty"<<endl; return false;//空队列处理
	}
	x=q[(front+1)%maxSize];
	return true;
}
template <class T>
bool SeqQueue<T>::EnQueue (T x){
	if (IsFull()){//溢出处理
		cout<<"队满"<<endl; return false;
	}
	q[(rear=(rear+1)%maxSize)]=x;
	return true;
}
template <class T>
bool SeqQueue<T>::DeQueue (){
	if(IsEmpty()){//空队列处理
		cout<<"队列下溢"<<endl; return false;
	}
	front=(front+1)%maxSize;
	return true;
}
template <class T>
void SeqQueue<T>::ListAll (){//输出队列里的所有元素
int temp;
int number=0;
temp=front;
if(front==rear)  {cout<<"队列无数据 !"<<endl;return;}
do{ cout<<q[temp+1]<<' ';
	temp=(temp+1)%maxSize;
}while(rear!=temp+1);
}
template <class T>
T SeqQueue<T>::IDfind(int i){//根据在队列里的序号找出相应元素
	int number=front;
	if(i==0)   return q[front+1];
	number=(number+1+i)%maxSize;
	return q[number];
}
//将中缀表达式转化为后缀表达式
template <class T>
class stack
{	public:
		virtual bool IsEmpty() const=0;
		virtual bool IsFull() const=0;
		virtual bool Top(T &x) const=0;
		virtual bool Push(T x)=0;
		virtual bool Pop()=0;
		virtual void Clear()=0;
};
template <class T>
class seqstack:public stack<T>

{
	public:
		seqstack(int mSize);
		~seqstack(){delete []s;}
		bool IsEmpty() const {return top==-1;}
		bool IsFull() const {return top==maxTop;}
		bool Top(T &x) const;//取出栈顶元素
		bool Push(T x);//压入栈
		void Clear(){top=-1;}//清空栈
		bool Pop();//弹出栈
	private:
		int top;//栈顶指针
		int maxTop;//最大栈顶指针
		T *s;
};
template <class T>
seqstack<T>::seqstack(int mSize)//初始化栈
{
	maxTop=mSize-1;
	s=new T[mSize];
	top=-1;
}
template <class T>
bool seqstack<T>::Top(T &x) const
{
	if(IsEmpty()){
		cout<<"栈空"<<endl;return false;
	}
	x=s[top];return true;
}
template <class T>
bool seqstack<T>::Push(T x)
{
	if(IsFull()){
		cout<<"栈上溢"<<endl;return false;
	}
	s[++top]=x;return true;
}
template <class T>
bool seqstack<T>::Pop()
{
	if(IsEmpty()){
		cout<<"栈下溢"<<endl;return false;
	}
	top--;return true;
}
//定义计算器类
class Calculator
{
public:
	Calculator(int maxSize):s(maxSize),suffix(maxSize) {};
	void Run();//从队列逐个读入字符,做相应的运算,输出结果
	void Clear(){s.Clear();suffix.Clear();}
private:
	SeqQueue<string> suffix;//存放转换后得到的后缀表达式队列对象
	seqstack <double> s;//声明存放操作数的栈对象
	void PushOperand(double);//操作数进栈
	bool GetOperands(double &,double &);//从栈中弹出2个操作数
	bool DoOperator(const char *per);
};
void Calculator::PushOperand(double op)
{
	s.Push(op);
}
bool Calculator::GetOperands(double &op1,double &op2)
{
	if(!s.Top(op1)){
		cerr<<"操作符多余"<<endl;return false;
	}
	s.Pop();
	if(!s.Top(op2)){
		cerr<<"操作符多余"<<endl;return false;
	}
	s.Pop(); return true;
}
bool Calculator::DoOperator(const char *oper)
{
	bool result;
	double oper1,oper2;
	result=GetOperands(oper1,oper2);//从栈中弹出2个操作数
	if(result){
		switch(*oper)
	//根据操作符做相应的运算,先出栈的操作数oper1
	//放在操作符的右边,后出栈的oper2放在左边
	{
          case '+':s.Push(oper2+oper1);break;
		  case '-':s.Push(oper2-oper1);break;
		  case '*':s.Push(oper2*oper1);break;
		  case '/':if (fabs(oper1)<1e-6){//如果分母为0,则做出错处理
			  cerr<<"Divide by 0!"<<endl;
			  Clear();return false;
				   }
			  else s.Push(oper2/oper1);break;
		  case '^':s.Push(pow(oper2,oper1));break;
	}
		return true;
	}
	else {Clear();return false;}
}
void Calculator::Run()
{
	const char * c;double newop;
	cout<<"请输入运算式!"<<endl;
	InfixToPostfix(suffix);//中缀转换为后缀
	int i=0;
	while(suffix.IDfind(i)!="="){//从队列中依次读入一个字符,遇'#'结束
		c=suffix.IDfind(i).c_str();
		i++;
		switch(*c){//从读入的字符做如下处理
		case '+':
		case '-':
		if(strlen(c)>1){
			newop=atof(c);
			PushOperand(newop);
			}
			else {if(DoOperator(c)==0) return;}  
			break;
		case '*':
		case '/':
		case '^':if(DoOperator(c)==0)   return;break;//是操作符则进行相应的计算
		default://如不是操作符,则转换为操作数
			newop=atof(c);
			PushOperand(newop);break;//操作数进栈
		}
	}
	if(s.Top(newop)){
		s.Pop();
		if(s.IsEmpty ()==1){
			cout<<"结果是:"<<newop<<endl;}//取到栈顶元素,并输出结果
		else cout<<"操作数多余"<<endl;
		Clear();
	}
}
void  InfixToPostfix(SeqQueue<string> &suffix0){
	seqstack<string>  s(SIZE);
	string ch, y;
    s.Push("=");
	while(cin>>ch,ch!="="){
		if(IsNumber(ch.c_str())) suffix0.EnQueue (ch);//扫描到操作数直接入队
		else if(ch==")") //扫描到右括号时的处理
			for(s.Top(y),s.Pop();y!="(";s.Top(y),s.Pop())
			    suffix0.EnQueue (y);
			else if(OperateSymbol(ch.c_str())) {//扫描到其他操作符时的处理
				for(s.Top(y),s.Pop();icp(ch.c_str())<=isp(y.c_str());s.Top(y),s.Pop()){
					suffix0.EnQueue (y);}//则弹出的m栈顶操作符优先级高时入队
			   s.Push(y);//当弹出的栈顶操作符的优先级低时, 将其重新压回栈中
			   s.Push(ch);//然后扫描到的操作符进栈
		}
        		else {
					cout<<"你输错"<<ch<<endl;
					s.Clear();
					suffix0.Clear();
					exit(1);
				}
	}
	while(!s.IsEmpty()){
		s.Top(y); s.Pop();
		if(y!="=") suffix0.EnQueue (y);
	}
	suffix0.EnQueue ("=");
}
void main()
{char c;
 cout<<"           欢迎使用本计算系统(笑^_^)"<<endl;
 cout<<"         注意 1.=表示算术式结束标志符!!!"<<endl;
 cout<<"              2.数字和符号之间用空格隔开"<<endl;
 Calculator Cal(SIZE);
 do{
 Cal.Run();
 cout<<"请输入组合键Ctrl+Z,再按回车结束,按其他键继续!!!"<<endl;
 c=cin.get();
 }while((c=cin.get())!=EOF);
 cout<<"谢谢使用...."<<endl;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -