RT。题目链接:
http://zju.acmclub.com/index.php?app=problem_title&id=1&problem_id=1743
求一表达式的值。需要注意的有以下几个方面:
1.首先想到的是先将中缀表达式转成后缀表达式,再扫描后缀表达式这一方法。扫描后缀表达式时,每遇到操作数时压栈,遇到操作符时从栈顶弹出2个操作数计算并压栈。最后返回栈顶即为结果。当然,题目中给的是算符优先法规定操作符之间的优先级。也可用其他的方式规定优先级。比如我的方法是事先规定好栈内优先级和栈外优先级。
2.其次,在转化后缀表达式的过程中,最好使用c++的泛型。因为如果用int型的数组来存储后缀式的话,操作符均变成ascii码来存储,有可能与操作数混淆。我的方法是操作符的ascii码减48(即操作符在后缀表达式中以负数形式出现,为了与操作数区分开)后再存储到数组中。另外,如果用char型数组来存后缀式的话,类似1234的多位操作数无法支持。
代码:
#include<iostream>
#include<cstring>
#define SIZE 100
using namespace std;
int main()
{
int isp[50];
int icp[50];
isp['#'] = 0;
isp['('] = 1;
isp['*']= isp['/'] = 5;
isp['+']= isp['-'] = 3 ;
isp[')'] = 6;
icp['#'] = 0;
icp['('] = 6;
icp['*']= icp['/'] = 4;
icp['+']= icp['-'] = 2 ;
icp[')'] = 1;//规定栈内优先级和栈外优先级
char str[SIZE];//存储输入字符串
int num_stack[SIZE];//计算后缀表达式时使用的栈
char op_stack[SIZE];//中缀表达式转后缀表达式时使用的栈
int top_num;
int top_op;
int i,j,k,sum;
int num[SIZE];
char buf;
int temp1,temp2;
while(cin>>str)
{
top_op = -1;
op_stack[++top_op] = '#';//操作符栈
j = 0;
for(i=0; i<strlen(str); i++)
{
if(str[i] <= '9' && str[i] >= '0')
{
sum = str[i] - '0';//操作数最高位先赋给sum
while(str[i+1] <= '9' && str[i+1] >= '0')
{
sum = sum * 10 + (str[i+1] - '0' );
i++;
}
//cout<<"sum="<<sum<<endl;
//num_stack[++top_num] = sum;//操作数直接进栈
num[j++] = sum ;
}
else//如果是操作符,则弹出栈顶元素比较优先级
{
//cout<<"top_op="<<top_op<<endl;
while(top_op > -1)
{
buf = op_stack[top_op];//返回操作符栈顶并比较
if(isp[buf] < icp[str[i]])
{
op_stack[++top_op] = str[i]; //进栈
break;
}
else if(isp[buf] > icp[str[i]])
{
num[j++] = op_stack[top_op--] - 48;//退栈并输出操作符
}
else //相等时直接退栈,也不要忘了break
{
top_op--;
break;
}
}
}
}
//扫描后缀表达式并输出
top_num = -1;//初始化数字栈,数字栈现在还没有使用
temp1 = temp2 = 0;
for(k=0; k<j; k++)
{
if(num[k]!=-1 && num[k]!=-3 && num[k]!=-5 && num[k]!=-6)
num_stack[++top_num] = num[k];//操作数入栈
else if (num[k] == -1)//匹配到除号
{
temp1 = num_stack[top_num--];
temp2 = num_stack[top_num--];
num_stack[++top_num] = temp2 / temp1;
}
else if (num[k] == -3)//匹配到减号
{
temp1 = num_stack[top_num--];
temp2 = num_stack[top_num--];
num_stack[++top_num] = temp2 - temp1;
}
else if (num[k] == -5)//匹配到加号
{
temp1 = num_stack[top_num--];
temp2 = num_stack[top_num--];
num_stack[++top_num] = temp2 + temp1;
}
else if (num[k] == -6)//匹配到乘号
{
temp1 = num_stack[top_num--];
temp2 = num_stack[top_num--];
num_stack[++top_num] = temp2 * temp1;
}
}
cout<<num_stack[top_num];//最后输出当前栈顶即可
cout<<endl;
}
}