字符串计算器(C++)

1.输入输出约定

输入一行字符串,包括数字,加减乘除,括号,输出答案。

不支持输入负数

不能整除时,向下取整

输入格式不正确时,输出“输入有误”

2.程序运行截图

3.思路解析

(1) 检查输入格式

(2)求逆元表达式 

(3)根据逆元表达式求解

4.求逆元表达式的方法

情况一:遇到左括号直接入栈,遇到右括号将栈中左括号之后入栈的运算符全部弹栈输出,同时左括号出栈但是不输出。

情况二:遇到乘号和除号直接入栈,直到遇到优先级比它更低的运算符,依次弹栈。

情况三:遇到加号和减号,如果此时栈空,则直接入栈,否则,将栈中优先级高的运算符依次弹栈(注意:加号和减号属于同一个优先级,所以也依次弹栈)直到栈空或则遇到左括号为止,停止弹栈。(因为左括号要匹配右括号时才弹出)。

情况四:获取完后,将栈中剩余的运算符号依次弹栈输出

5.完成代码(编译器:devc++)

#include<iostream>
#include<string.h>
#include<stack>
using namespace std;
char in[200];
int doit[200];
int doi;

bool miss(char a){
	return a=='+'||a=='-'||a=='*'||a=='/';
}
bool mrs(char a){
	return a<='9'&&a>='0';
}
int mr(char a){
	if(a=='+') return -1;
	if(a=='-') return -2;
	if(a=='*') return -3;
	if(a=='/') return -4;
}
bool check(){
	stack <char> ff;
	int haveshu=0;
	int havefu=0;
	for(int i=0;i<strlen(in);i++){
		//括号匹配错误 
		if(in[i]=='(') ff.push('(');
		if(in[i]==')'){
			if(!ff.empty()&&ff.top()=='('){
				ff.pop();
			}
			else{
				return false;
			}
		}
		//输入非法错误 
		if(i>0&&miss(in[i])&&miss(in[i-1])) return false;//运算符连用 
		if(i==0&&miss(in[i])) return false;//首尾为操作符 
		if(i==strlen(in)-1&&miss(in[i])) return false;
		if(i>0&&in[i-1]=='('&&miss(in[i])) return false;
		if(i>0&&in[i+1]==')'&&miss(in[i])) return false;
		
		if(mrs(in[i])||miss(in[i])||in[i]=='('||in[i]==')')  ;
		else return false;
		
		if(mrs(in[i])) haveshu++;
		if(miss(in[i])) havefu++;
	}
	
	if(!ff.empty()) return false;
	if(!haveshu) return false;
	if(!havefu) return false;
	return true;
}

void niyuan(){
	int shuzi=0;
	stack <char> cc;
/*
情况一:遇到左括号直接入栈,遇到右括号将栈中左括号之后入栈的运算符全部弹栈输出,同时左括号出栈但是不输出。

情况二:遇到乘号和除号直接入栈,直到遇到优先级比它更低的运算符,依次弹栈。

情况三:遇到加号和减号,如果此时栈空,则直接入栈,否则,将栈中优先级高的运算符依次弹栈(注意:加号和减号属于同一个优先级,所以也依次弹栈)直到栈空或则遇到左括号为止,停止弹栈。(因为左括号要匹配右括号时才弹出)。

情况四:获取完后,将栈中剩余的运算符号依次弹栈输出

*/


	for(int i=0;i<strlen(in);i++){
		if(mrs(in[i])){ 
			shuzi=shuzi*10+(in[i]-'0');
			if(i==strlen(in)-1||!mrs(in[i+1])){
				doit[doi]=shuzi;
				doi++;
				shuzi=0;
			}
			continue;
		}
		
		if(cc.empty()||in[i]=='('){
			cc.push(in[i]);
			continue;
		}
		
		if(in[i]=='*'||in[i]=='/'){
			while(!cc.empty()&&cc.top()!='('&&cc.top()!='+'&&cc.top()!='-'){
				doit[doi]=mr(cc.top());
				cc.pop();
				doi++;
			}
			cc.push(in[i]);
			continue;
		}
			
		if(in[i]=='+'||in[i]=='-'){
			while(!cc.empty()&&cc.top()!='('){
				doit[doi]=mr(cc.top());
				cc.pop();
				doi++;
			}
			cc.push(in[i]);
			continue;
		}
		
		if(in[i]==')'){
			while(!cc.empty()){
				if(cc.top()=='('){
					cc.pop();
					break;
				}
				doit[doi]=mr(cc.top());
				cc.pop();
				doi++;
			}
			
			continue;
		}
		
	}
	
	while(!cc.empty()){
		doit[doi]=mr(cc.top());
		cc.pop();
		doi++;
	}
}
int qiujie(){
	/*for(int i=0;i<doi;i++){
		if(doit[i]>=0) cout<<doit[i]<<" ";
		else{
			if(doit[i]==-1) cout<<"+ ";
			if(doit[i]==-2) cout<<"- ";
			if(doit[i]==-3) cout<<"* ";
			if(doit[i]==-4) cout<<"/ ";
		}
	}*/
	stack <int> sz;
	int dd,dt;
	for(int i=0;i<doi;i++){
		if(doit[i]>=0){
			sz.push(doit[i]);
		}
		else{
			dd=sz.top();
			sz.pop();
			dt=sz.top();
			sz.pop();
			if(doit[i]==-1) sz.push(dt+dd);
			if(doit[i]==-2) sz.push(dt-dd);
			if(doit[i]==-3) sz.push(dt*dd);
			if(doit[i]==-4&&dd!=0) sz.push(dt/dd);
			if(doit[i]==-4&&dd==0) {
				cout<<"除数为零!";
				return 0; 
			}
		}
	}
	return  sz.top();
}
int main(){
	while(1){//采用循环输入 
		doi=0;
	    cin.getline(in,200);//表达式最高可到200,不支持小数 负数 
	    if(!check()){//检查输入格式 
	    	cout<<"输入有误"<<endl;
	    	cout<<endl;
		    continue;
	    }
		niyuan();	//先求逆元表达式 
		cout<<qiujie()<<endl;//再根据表达式求解 
		cout<<endl;
	}
	
	
	return 0;
}

 -------------------------------------

尊敬的开发者,您好!我是一名初入职场的小小程序员,从事软件开发工作,定期发一些文章来记录自己的学习过程,并分享问题的解决方法。

如果样例代码和文章描述有哪些问题,或者有相关领域想一起讨论,欢迎私信交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值