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

📄 jsq.cpp

📁 计算器程序
💻 CPP
字号:
#include <iostream>
using namespace std;


const int maxstack=30;
enum Error_code {success,underflow,overflow};

     /* 栈的定义*/

template<class Stack_entry>
class Stack                        
{
public:
	Stack();
	Error_code push(const Stack_entry &item);  //进栈
	Stack_entry top() const;                   //取栈顶值
	Error_code pop();                          //出栈
	bool isEmpty() const;                      //判空
	void setnull()                             //清空
	{
		count=0;
	};
private:
	int count;
	Stack_entry container[maxstack];           //栈数组
};

template<class Stack_entry>
Error_code Stack<Stack_entry>::push(const Stack_entry &item)//进栈
{
	Error_code result=success;
	if(count>=maxstack)
		result=overflow;
	else
		container[count++]=item;
	return result;
}
template<class Stack_entry>
Error_code Stack<Stack_entry>::pop()//出栈
{
	Error_code result=success;
	if(count<=0)
		result=underflow;
	else
		count--;
	return result;
}
template<class Stack_entry>
Stack_entry Stack<Stack_entry>::top() const//取栈顶值
	{
	if(count!=0) 
	return container[count-1];
	}

template<class Stack_entry>
Stack<Stack_entry>::Stack()
{
	count=0;
}
template<class Stack_entry>
bool Stack<Stack_entry>::isEmpty() const//判空
{
	return count==0;
}

/*定义计算器类*/
class calculator                   
{
private:
	Stack<char> optr;              //定义运算符的栈
	Stack<double> opnd;            //定义运算数的栈
	
	
public:
	calculator(){                  //构造函数
		optr.setnull();
		opnd.setnull();
		optr.push('=');
	};
	void evaluate();
	void clear(){                  //清空
		optr.setnull();
		opnd.setnull();
		optr.push('=');
	};
private:
	int lp(char op);                  //运算符优先级权值表
	int rp(char op);
	double operate(char theta,double a, double b);  
};

double calculator::operate(char theta,double a, double b){//根据运算符进行相应的运算操作
	switch(theta){
	case '+': return a+b;
		break;
	case '-': return a-b;
		break;
	case '*': return a*b;
		break;
	case '/': return a/b;
		break;
	}
}
int calculator::lp(char op){           //根据运算符返回相应的优先级权值
	switch(op)
	{
		case '+': return 3;
		break;
	    case '-': return 3;
		break;
	    case '*': return 5;
		break;
	    case '/': return 5;
		break; 
		case '(': return 1;
	    break;
		case ')': return 6;
	    break;
		case '=': return 0;
	    break;
		
	}
}
int calculator::rp(char op){           //根据运算符返回相应的优先级权值
	switch(op)
	{
		case '+': return 2;
		break;
	    case '-': return 2;
		break;
	    case '*': return 4;
		break;
	    case '/': return 4;
		break; 
		case '(': return 6;
	    break;
		case ')': return 1;
	    break;
		case '=': return 0;
	    break;
		default: return -1;  //如果输入非法字符返回-1
		break;
		
	}
}
void calculator::evaluate()
{
	char ch,op,theta;
	double val,a,b;
	bool ill=true;         //ill变量来判断表达式是否合法
	int bracket=0;         //bracket=0为括号匹配;输入'('自加一,输入')'自减一
	int jocket1=0;         //记录运算符个数; 依据运算数数量减运算符(+-*/)数量恒等于一
	int jocket2=0;         //记录运算数个数; (不包含负数的运算)
	cin>>ch;
	op='=';
	while((ch!='=')||(op!='=')){       //若ch=op='='则运算结束,结果在opnd栈顶
		
		if(!isdigit(ch)){
		if(rp(ch)==-1) //如果为非法字符显示错误提示
			  {
			   cout<<"请输入合法的表达式"<<endl;
		       ill=false;                         //非法表达式ill变量赋值为false
			   break;
			  }
		}
		
		if(ch=='(') bracket++; //输入一个左括号bracket变量自加一
		else
		{
		if(ch==')') {
			if(bracket>0)	bracket--;//bracket大于零控制右括号必须在左括号输入后才可输入
			                          //输入一个右括号bracket变量自减一
		}
		}

		
		
		

		
		if(isdigit(ch)){               //若为运算数压入opnd栈
            
			cin.putback(ch);           //读取运算数
			cin>>val;
			opnd.push(val);
			jocket2++;  //每输入一个运算数jocket2自加一
			cin>>ch;
		}
		else {

			 if(lp(op)<rp(ch))  /*读入的运算符优先级高于optr栈顶
				               的运算符则将其压入optr栈 */
			 {
			    if(ch=='+'||ch=='-'||ch=='*'||ch=='/') jocket1++;//每输入一个运算符jocket1自加一
				optr.push(ch);
			    cin>>ch;
			 }
			 else			
		          if(lp(op)==rp(ch))/*读入的运算符优先级等于optr栈顶
				                   的运算符则退出optr栈顶元素'('*/
				  {			
			        optr.pop();
		 	        cin>>ch;
				  }
		          else             /*读入的运算符优先级低于optr栈顶
				                     的运算符则退出optr栈顶元素退出opnd两个元素
								     进行计算*/
				  {
			        theta=optr.top();
			        optr.pop();
			        b=opnd.top();
			        opnd.pop();
			        a=opnd.top();
			        opnd.pop();
			        opnd.push(operate(theta,a,b));
				  }      
	
		}
		op=optr.top();
		}

    if(bracket!=0)//判断是否括号匹配
		cout<<"括号不匹配"<<endl;
	else
	{
		if(jocket2-jocket1==1){                        //正确表达式运算数始终比运算符多一
		    if (ill) cout<<opnd.top()<<endl;           //判断表达式是否合法
		}        
	    else cout<<"运算符错误"<<endl;
	}
}



void main(){
	calculator jsq;
	cout<<endl<<"现在进行表达式计算(y/n):";
	char item;
	
	cin>>item;
    while(item=='y')
	{
		cout<<endl<<"请输入表达式以=号键结束(只限30个字符之内)"<<endl;
	    cout<<"表达式:";
	    jsq.evaluate();
	    char *a=new char[30];
		cin.getline(a,30);       //读入以前表达式不正常退出所遗留的字符
		delete[] a;              //将其删除 以备重新读入新的表达式
		cout<<endl<<"是否继续进行表达式计算(y/n):";
		cin>>item;
	}
}

⌨️ 快捷键说明

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