【C/C++】模拟计算器(计算中缀表达式)

这是我们C++的一个小小的课程设计;

因为时间比较短,支持的运算符就只有“+”,“-”,“x”,"/","%","#"(幂)。

核心部分推荐参考:

https://baike.baidu.com/item/%E5%90%8E%E7%BC%80%E8%A1%A8%E8%BE%BE%E5%BC%8F/6160580?fr=aladdin

主要是看懂中缀表达式转换为后缀表达式的规则,以及后缀表达式(逆波兰式)的计算方法,其他的就简单了。

主流程:

后缀表达式计算方法:

推荐使用链栈结构,自行百度,我这里纯粹使用了一个结构体,但是整体上也是拿这个当做栈那样用,具体的,看代码吧:

#include
#include
#include
#include
#include
#include
#include
#include
#include 
using namespace std;
typedef long long ll;

struct mix{
	char Oper;           //运算符 
	double num;          //数字 
	int sign;            //标记,存数字用num,标记为1,存运算符用Oper,标记为2 
};


mix nifix[10000000];          //储存中缀表达式 
int q=0;                      //记录nifix数组大小
string a;                     //读入字符串 
stack tool;             //保存运算符 
vector  suffix;          //保存后缀表达式


int  priority(char s){        //给操作符赋予优先级 
	
	switch (s){
	case '(':return 0;        //这里是为了方便操作括号,实际上"()"优先级大 
		case '+':
			case '-':
			    return 1;
		case '*':
		    case '/':
		    	case '%':
		    	    return 2;
		case '#':return 3;    	
					 
	}
}


double calcu(double a,double b,char s){
	
	switch (s){
		case '+' : return a+b;
		case '-' : return a-b;
		case '*' : return a*b;
		case '/' : return a/b;
		case '%' : return (ll)a%(ll)b; 
		 //一开始用的强转int,double转int存在误差,所以换成了long long  
		case '#' : return pow(a,b);
	}
	
}


bool judge(string s){       //判断表达式是否合法 
 	 int n=s.length();
	 bool f=false;
	 stack t;
	 for(int i=0;i='0'&&a[i]<='9')){
	 	    	if(a[i]!='+'&&a[i]!='-'&&a[i]!='*'&&a[i]!='/'&&
				 a[i]!='#'&&a[i]!='.'&&a[i]!='%'&&a[i]!='('&&a[i]!=')'){
	 	    		f=true; 
	 	    		break;  
				 }
			}               //有非法标识符,直接标记f为true并退出循环 
			if(s.substr(i,2)=="/0"){
				f=true;     //每次截取长度为2的子串 
				break;      //0不能做除数 
			} 
	 	    if(t.empty()&&a[i]==')'){
	 		   f=true;
	 		   break;          
		    }
		    if((s[n-1]<'0'||s[n-1]>'9')&&s[n-1]!=')'){
		    	f=true;        //表达式最后一位不是数字或者')'的不合法 
		    	break; 
			}
	        if(a[i]=='('){
	     	   t.push(a[i]);   //左括号入栈 
		    }
			if(a[i]==')'){     //每有一个右括号,弹出一个左括号 
				t.pop();        
			}	
	 }
	 if(t.empty()&&!f){      //括号匹配(栈空)并且符合其他条件,表达式合法 
	 	return true;          
     }
     return false;
	                           
}


string dealneg(string str){               //处理字符串里的负数 ,补0. 
	for(int i=0;i='0'&&a[i]<='9'||a[i]=='.'){
    		string temp="";
    		int l=i;
    		while(a[l]>='0'&&a[l]<='9'||a[l]=='.'){  //实数用一个string保存, 
     			temp+=a[l]; 					     
				 //不直接用char数组,是因为操作的对象长度未知,char数组大小不好确定 
    			l++;
			}
			
			temp+='\0';
			int y=temp.length();        //string 转 字符数组 
			char ss[y];                  
			for(int z=0;zpriority(tool.top())){   //这里要注意判断栈是不是空 
					tool.push(nifix[i].Oper); //运算符优先级大于栈顶元素,入栈 
				}
				else if(nifix[i].Oper=='('){
					tool.push('(');           //左括号入栈 
				}
				else if((tool.empty())||priority(nifix[i].Oper)<=priority(tool.top())){
					int y=priority(nifix[i].Oper);                 //运算符优先级小于等于栈顶元素 
					while((!tool.empty())&&priority(tool.top())>=y){
					    r.Oper =tool.top();
						r.sign =2;
						suffix.push_back(r);    //保存到后缀表达式并弹出 
						tool.pop(); 
					}
					tool.push(nifix[i].Oper);   //将这个运算符入栈 
			}	
		}
		 
	}
	
	while(!tool.empty()){
		r.Oper =tool.top();   //以上步骤进行完,栈里还有运算符,全部弹出,存到后缀表达式 
		r.sign =2;
		suffix.push_back(r);    
		tool.pop(); 
	}	
} 


double result(){                                     //后缀表达式计算 
	int o=suffix.size();
	    while(suffix.size()!=1){
	    	int i=0;
	       for(;i<=o-3;){
	       	  if((i+2='0'&&a[0]<='9')    
		return true;
		return false;
	}
	else{
			if(a[0]=='+'||a[0]=='-') 
	   //第一位是'+','-',(这里不再处理带括号的单个实数,认为它是合法的) 
			{
				if(a[1]=='.') return false;
				else{
					 for(int i=2;i'9'))
						return false;
					}
					return true;
				}
			}
			else if(a[0]>='0'&&a[0]<='9'){  //第一位是数字 
			for(int i=1;i'9'))
					return false;
					}
					return true;
			}
		} 
}


void screen(){
	system("cls");
	cout<<"\t\t\t\t☆☆☆-----------------------------------------☆☆☆"<>a){
		if(a=="@") {
			cout<='0'&&a[0]<='9')
			 cout<().swap(suffix);    
			    q=0;
			    getchar();
			    getchar();
			    screen();
		}
	}
	return 0;
} 

 

你可能感兴趣的:(学习笔记,学习笔记)