逆波兰式,即后缀表达式。代码如下:
#include <stack>
#include <map>
#include <conio.h>
#include <string.h>
#include <ctype.h>
#define MAX 1000
using namespace std;
//函数原型
void rpn_print_stack(char *input);
int main()
{
char test[]="(a+b)*c-(a+b)/e#";//测试用例
rpn_print_stack(test);
getch();
}
//打印逆波兰式(利用栈实现)
void rpn_print_stack(char *input)
{
//定义
int length=strlen(input);//表达式的长度
stack<char> s1;//存储运算符
stack<char> s2;//存储逆波兰式的逆序
//利用map实现优先级
map<char,int> operation;
operation['#']=0;
operation['(']=1;
operation['+']=2;
operation['-']=2;
operation['*']=3;
operation['/']=3;
//进行操作
s1.push('#');//初始时存在#,设#为最低优先级
for(int i=0;i<length;i++)
{
char top_char=s1.top();//得到s1的栈顶元素
if(isalpha(input[i])) //如果为操作数,直接进s2
{
s2.push(input[i]);
}
else if(input[i]=='#')//表达式的结束标志
{
while(top_char!='#')
{
s2.push(top_char);
s1.pop();
top_char=s1.top();
}
}
else if(input[i]=='(') //如果为'(',直接进s1
{
s1.push('(');
}
else if(input[i]==')') //把成对操作数的运算符压入s2
{
while(top_char!='(' )
{
s2.push(top_char);
s1.pop();
top_char=s1.top();
}
s1.pop();//去除与当前')'成对的'('
}
else if(operation[input[i]]>operation[top_char]) //如果操作符的优先级大于当前栈顶,则进s1
{
s1.push(input[i]);
}
else if(operation[input[i]]<=operation[top_char]) //如果操作符的优先级小于当前栈顶
{
while(operation[input[i]]<=operation[top_char] && input[i]!='#')
{
s2.push(top_char);//将s1的栈顶入s2
s1.pop();
top_char=s1.top();
}
s1.push(input[i]);
}
}
//逆序s2,得到逆波兰式
char result[MAX];
int j=0;
char top_char=s2.top();
while(!s2.empty())
{
result[j]=top_char;
j++;
s2.pop();
if(s2.size()>0)//注意这里,栈中最后一个元素出栈后,不能再求其top
top_char=s2.top();
}
//打印逆波兰式
for(int m=j-1;m>=0;m--)
printf("%c",result[m]);
}
总结:算法很简单,但是写多个if else的时候逻辑容易出错,有两个语句调换了位置就会有问题。