后缀表达式
题目描述
输入一个中缀表达式,利用栈及运算符间的优先关系将中缀表达式转换为后缀表达式,然后只需要一个操作数栈即可对后缀表达式求值得到结果。
【输入输出示例】
输入:9+(23*8)-12#
输出:9 23 8 * + 12 -#(后缀表达式)
181(表达式计算的结果)
算法描述
(1)Ints(char str1,char str2)函数算法描述
算法:Ints
输入:char str1,char str2;
输出:如果str1 = + 或 -,如果 str2 = ( 或 # 返回 1 ,反之返回 -1 ;
如果str1 = * 或 /,如果 str2 = * 或 / 返回 -1 ,反之
反回 1 ;
如果str1 = (,返回1;
如果str1 = ),如果str2 = ( 返回0,反之返回-1;
如果str1 = #,如果str2 = # 返回0,反之返回-1;
(2)Against_Poland(string str)函数算法描述
算法:Against_Poland
输入:string str
输出:无输出
1.定义字符串Poland,将栈Oper初始化为表达式的定界符#
2.从左到右扫描表达式的每一个字符执行下述操作:
2.1若当前字符是数字就进入Poland。
2.2若当前字符是运算符且优先级比栈Oper的栈顶运算符的优先级高,则入栈Oper,处理下一个字符
2.3若当前字符是运算符且优先级比栈Oper的栈顶运算符的优先级低,则该运算符出栈进入Poland中
2.4若当前字符是运算符且优先级与栈Oper的栈顶运算符的优先级相同,则将Oper的栈顶元素出栈
(3)Calculation()函数算法描述
算法:Calculation
输入:无
输出:算式计算结果
1.定义字符型数组Num
2.从左到右扫描逆波兰式的每个字符执行相应的操作
2.1 如果当前字符是数字则进入Num.
2.2 如果当前字符是运算符则从Num栈中输出两个数字进行运算,并将结果入栈
3. 返回Num的栈顶元素即为运算结果。
流程图
代码
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
const int N = 110; //计算式长度
int top1 = -1;
string Poland[N]; //逆波兰式存在该数组中
int idx;
int Ints(char str1,char str2)//比较运算符优先级,1表示str1优先级大于str2,-1反之,0则存运算符的栈弹出栈顶元素
{
switch(str1)
{
case'+':case'-':if(str2 == '(' || str2 == '#') return 1;else return -1;break;
case'*':case'/':if(str2 == '*' || str2 == '/') return -1; else return 1;break;
case'(':return 1;break;
case')':if(str2 == '(') return 0;else return -1;break;
case'#':if(str2=='#') return 0;else return -1;break;
default:break;
}
}
void Against_Poland(string str)//得到逆波兰式
{
char Oper[N]; //存运算符
int top2 = 0;
Oper[top2] = '#';
for(int i=0;str[i]!='\0';)
{
while(str[i] >= 48 && str[i] <= 58)
{
Poland[idx]+=str[i++]; //将数字存入逆波兰式
}
idx++;
int k = Ints(str[i],Oper[top2]); // 判断运算符优先级
if(k == 1)Oper[++top2] = str[i++];
else if (k==-1)
{
Poland[idx++]=Oper[top2--];//将运算符存入逆波兰式
}
else
{
i++;
top2--;
}
}
}
double Calculation()//逆波兰式计算结果
{
double Num[N];
double z,y,x;
for(int i = 0;i < idx;i++){
string s = Poland[i];
if(s[0] >= 48 && s[0] <= 58) //将字符串还原成double类型的数据
{
double t=0;
for(int j = 0; j < s.size(); j ++ )
{
double tt = (double)(s[j]-48);
t +=tt*pow(10,s.size()-j-1);
}
Num[++top1] = t;
}
else if(s[0]=='+'||s[0]=='-'||s[0]=='/'||s[0]=='*')//计算,Num栈中取出两个值,再将计算结果存入栈中
{
char op = s[0];
y = Num[top1--];
x = Num[top1--];
switch(op)
{
case'+':z = x + y;break;
case'-':z = x - y;break;
case'*':z = x * y;break;
case'/':z = x / y;break;
default:break;
}
Num[++top1] = z;
}
}
return Num[top1];
}
int main()
{
string str;
cout << "输入一个表达式: " ;
cin >>str;
Against_Poland(str);
cout << "逆波兰是为:";
for(int i = 0; i < idx; i ++ )
{
cout << Poland[i] <<" ";
}
cout << '#'<<endl;
cout << "结果为:";
cout << Calculation() << endl;
return 0;
}