HDOJ 1237 简单计算器

核心部分伪代码:

stack 符栈,数栈;
c=getchar()
while(c!='\n' || !符栈.empty()){
	if(c是操作数) 数栈.push();c=getchar();
	else if(符栈.empty()) 符栈.push(c);c=getchar();
	else switch(precede(符栈.top(),c)){//比较栈运算符和当前运算符的优先级
				case '<': 符栈.push(c); c=getchar();break;
				case '=': 符栈.pop(); c=getchar();break;//脱括号
				case '>': { //栈顶优先级更高,运算 
					b=数栈.top();数栈.pop();
					a=数栈.top();数栈.pop();
					o=符栈.top();符栈.pop();
					数栈.push(operate(a,o,b));
					break;//不需要getchar(),因为当前c还没有任何操作
				}
			}
}
printf(数栈.top())

实现的时候需要注意:数据类型,操作数是多位数。
除了本篇的思路,计算器还可以用中缀表达式和后缀表达式(逆波兰表达式)实现。

//只有四则运算
#include<bits/stdc++.h>
using namespace std; 
char precede(char a, char b){ //运算符的优先关系 
	char mark[4][4] = { {'>','>','<','<'},
						{'>','>','<','<'},
						{'>','>','>','>'},
						{'>','>','>','>'}
	};
	char ch[4]={'+','-','*','/'};
	for(int i=0;i<4;i++){
		if(a==ch[i])
			for(int j=0;j<4;j++)
				if(b==ch[j]) return mark[i][j];
	}
}
double operate(double a, char o, double b){ //二元运算 
	switch(o){
		case '+': return a+b;
		case '-': return a-b;
		case '*': return a*b;
		case '/': return a/b;
	}
}
int main (){
	string s;
	stack<double>digit; //操作数栈 
	stack<char>mark;  //运算符栈 
	double op1;
	double a,b;
	char o; 
	while(getline(cin, s) && s != "0") {
        for(int i=0; s[i]; i++) { //跳过空格,获取到的就只有数字或者符号 
            if(s[i]==' ') continue;
			else if(isdigit(s[i])) {
                op1 = 0;
                while(isdigit(s[i])) {
                    op1 = op1 * 10 + s[i] - '0';
                    i++;
                }
                i--;
                digit.push(op1);
            }else if(mark.empty()) mark.push(s[i]); //在第一个运算符的时候字符栈里是空的 
			else switch(precede(mark.top(),s[i])){ //比较当前运算符和栈运算符的优先级 
				case '<': mark.push(s[i]); break;
				case '>': { //栈顶优先级更高,就进行运算 
					b=digit.top();digit.pop();
					a=digit.top();digit.pop();
					o=mark.top();mark.pop();
					digit.push(operate(a,o,b));
					i--;
					break;
				}
			}
		}
		while(!mark.empty()){ //这个时候,只剩下前面低优先级运算符和一个高优先级运算符,以及操作数 
				b=digit.top();digit.pop();
				a=digit.top();digit.pop();
				o=mark.top();mark.pop();
				digit.push(operate(a,o,b));
		}
		printf("%.2f\n",digit.top());
	}
	return 0;
}
//四则运算和括号.略微修改上面的就行
#include<bits/stdc++.h>
using namespace std; 
char precede(char a, char b){ //运算符的优先关系 
	char mark[6][6] = { {'>','>','<','<','<','>'},
						{'>','>','<','<','<','>'},
						{'>','>','>','>','<','>'},
						{'>','>','>','>','<','>'},
						{'<','<','<','<','<','='},
						{'>','>','>','>',' ','>'}
	};
	char ch[6]={'+','-','*','/','(',')'};
	for(int i=0;i<6;i++){
		if(a==ch[i])
			for(int j=0;j<6;j++)
				if(b==ch[j]) return mark[i][j];
	}
}
double operate(double a, char o, double b){ //二元运算 
	switch(o){
		case '+': return a+b;
		case '-': return a-b;
		case '*': return a*b;
		case '/': return a/b;
	}
}
int main (){
	string s;
	stack<double>digit; //操作数栈 
	stack<char>mark;  //运算符栈 
	double op1;
	double a,b;
	char o; 
	while(getline(cin, s) && s != "0") {
        for(int i=0; s[i]; i++) { //跳过空格,获取到的就只有数字或者符号 
            if(s[i]==' ') continue;
			else if(isdigit(s[i])) {
                op1 = 0;
                while(isdigit(s[i])) {
                    op1 = op1 * 10 + s[i] - '0';
                    i++;
                }
                i--;
                digit.push(op1);
            }else if(mark.empty()) mark.push(s[i]); //在第一个运算符的时候字符栈里是空的 
			else switch(precede(mark.top(),s[i])){ //比较当前运算符和栈运算符的优先级 
				case '<': mark.push(s[i]); break;
				case '=': mark.pop(); break; 
				case '>': { //栈顶优先级更高,就进行运算 
					b=digit.top();digit.pop();
					a=digit.top();digit.pop();
					o=mark.top();mark.pop();
					digit.push(operate(a,o,b));
					i--;
					break;
				}
			}
		}
		while(!mark.empty()){ //这个时候,只剩下前面很多低优先级运算符和一个高优先级运算符,以及操作数 
				b=digit.top();digit.pop();
				a=digit.top();digit.pop();
				o=mark.top();mark.pop();
				digit.push(operate(a,o,b));
		}
		printf("%.2f\n",digit.top());
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

正在学C++

2角不嫌多,1角不嫌少

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值