表达式
表达式 = 操作数(运算对象) + 操作符(运算符) + 分界符
算数表达式有三种表示:(逆波兰表达式又称为后缀表达式)
- 中缀表达式(infix):<操作数><操作符><操作数>例如:A+B
- 前缀表达式(prefix):<操作符><操作数><操作数>例如:+AB
- 后缀表达式(postfix):<操作数><操作数><操作符>例如:AB+
C++中操作符的运算优先级:
优先级 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
操作符 | 单目一,! | *,/% | +/- | <,<=,>=,> | ==,!= | && | || |
由于中缀表达式有操作符优先级问题,需要使用两个栈才能解决问题,所以一般使用后缀表达式进行计算。
详解后缀表达式
A B C D - * + E F / -
步骤 | 输入项 | 项类型 | 操作 | 栈内容 |
---|---|---|---|---|
1 | 置空栈 | 空 | ||
2 | A | 操作数 | 进栈 | A |
3 | B | 操作数 | 进栈 | A B |
4 | C | 操作数 | 进栈 | A B C |
5 | D | 操作数 | 进栈 | A B C D |
6 | - | 操作符 | D,C出栈,计算C-D,结果R1进栈 | A B R1 |
7 | * | 操作符 | R1,B出栈,计算B*R1,结果R2进栈 | A R2 |
8 | + | 操作符 | R2,A出栈,计算A+R2,结果R3进栈 | R3 |
9 | E | 操作数 | 进栈 | R3 E |
10 | F | 操作数 | 进栈 | R3 E F |
11 | / | 操作符 | F,E出栈,计算E/F,结果R4进栈 | R3 R4 |
12 | - | 操作符 | R4,R3出栈,计算R3-R4,结果R5进栈 | R5 |
代码实现
#include<stdlib.h>
#include<iostream>
#include<stack>
#include<ctype.h>
using namespace std;
class Calculator{
public:
//构造函数
Calculator()
{}
void Run();//执行表达式计算---后缀表达式
void clear();//清除栈空间
private:
stack<double> s;
void AddOperand(double value);//操作数进栈
bool Get2Operand(double& left, double& right);//两个操作数出栈
void DoOperand(char op);//形成运算指令,进行计算
};
//操作数进栈
void Calculator::AddOperand(double value){
s.push(value);//将操作数进栈
}
//两个操作数出栈
bool Calculator::Get2Operand(double& left, double& right){
if (s.empty() == true)//判断栈是否为空
{
cout << "缺少右操作数!" << endl;
return false;
}
right = s.top();
s.pop();
if (s.empty() == true)//判断栈是否为空
{
cout << "缺少左操作数!" << endl;
return false;
}
left = s.top();
s.pop();
return true;
}
//形成运算指令,进行计算
void Calculator::DoOperand(char op){
double left, right;//待计算的左值和右值
double result;//计算的结果
if (Get2Operand(left, right) == true){
switch (op){
case '+':
result = left + right;
s.push(result);
break;
case '-':
result = left - right;
s.push(result);
break;
case '*':
result = left * right;
s.push(result);
break;
case '/':
if (right == 0.0){//除法运算时,右值不能为零
cerr << "右值为零!" << endl;
clear();
}
else{
result = left / right;
s.push(result);
}
break;
default:
clear();
}
}
else
clear();
}
//读字符串并求一个后缀表达式的值,以字符'='结束
void Calculator::Run(){
char ch;
double newOperand;
while (cin >> ch, ch != '='){//读入字符
switch(ch){
case'+':case'-':case'*':case'/'://判断是否为操作符
DoOperand(ch);
break;
default:
cin.putback(ch);//将ch放回,以便重新以double类型读入
cin >> newOperand;
AddOperand(newOperand);
}
}
if (ch == '=')
{
newOperand = s.top();
cout << newOperand << endl;
}
}
//清除栈空间
void Calculator::clear(){
s.empty();
}
int main()
{
Calculator c;
while (1){
cout << "请输入操作数和操作符,以'='结束:" << endl;
c.Run();
c.clear();
fflush(stdin);
}
return 0;
}