//中缀表达式的计算
//将输入的算术表达式存储到字符串 S 中;
//建立并初始化操作数栈和运算符栈,并将‘#’压入运算符栈;
//建立二维数组存储算术运算符的优先关系;
//建立并初始化一个临时栈T用来处理多位数或小数;
// 依次(循环)读.. ch 是操作数,将其入临时栈;
/*当读入的字符 ch 是运算符:
将临时栈中的数据转化为整数或小数(这需要编写个函数),
并将转化后的数据入操作数栈,清空临时栈;
// 根据运算符栈的栈顶元素和 ch 的优先权比较结果,做不同的处理:
a)若是小于,则 ch 压入运算符栈,读入下一个字符;
//b)若是大于,则弹出运算符栈顶的运算符,从操作数栈弹出两个数,进行相
//应运算,将结果压入操作数栈;
c)若是等于,则运算符栈顶元素是‘(’且 ch 是‘)’,这时弹出运算符栈顶的
‘(’,相当于去括号,然后读入下一个字符;
d)当读入的字符 ch 是‘#’,且运算符栈顶元素也是‘#’时,
算法结束。*/
输入示例:
/*
2+3+5*6-(8+2)-6/2
>><<<>
>><<<>
>>>><>
>>>><>
<<<<<=
*///下面代码中注释部分是写作是验证用的,读者可以直接删除或者忽视,在代码中不起任何作用!
#include<iostream>
using namespace std;
#define MAXSIZE 20
#define N 10
//运算符栈
typedef struct
{
char *base;
char *top;
int size;
}stack1;
//操作数栈
typedef struct
{
int *base;
int *top;
int size;
}stack2;
//为什么没有必要建一个临时栈
//运算符栈的初始化
void init1(stack1 &S)
{
S.base=new char[MAXSIZE];
S.top=S.base;
S.size=MAXSIZE;
// *S.top++='#';//讨论*S.top++=和S.top++
}
//操作数栈的初始化
void init2(stack2 &S)
{
S.base=new int[MAXSIZE];
S.top=S.base;
S.size=MAXSIZE;
}
//运算符入栈
void push1(stack1 &S,char e)
{
if(S.top-S.base==S.size)
exit(0);
*S.top++=e;
}
//操作数入栈
void push2(stack2 &S,char e)
{
if(S.top-S.base==S.size)
exit(0);
*S.top++=e-48;
}
//运算符出栈
void pop1(stack1 &S,char &e)
{
if(S.base==S.top)
exit(0);
e=*--S.top;
}
//操作数出栈
void pop2(stack2 &S,int &e)
{
if(S.base==S.top)
exit(0);
e=*--S.top;
}
int verify(char ch)
{
//cout<<ch<<endl;
if(ch=='+')
return 0;
else if(ch=='-')
return 1;
else if(ch=='*')
return 2;
else if(ch=='/')
return 3;
else if(ch=='(')
return 4;
else if(ch==')')
return 5;
else
{
//cout<<ch<<endl;
//cout<<"此时运算符栈为空!"<<endl;
return 100;
}
}
//判断并计算
int judge(int a,char e,int b)
{
//cout<<e<<endl;
if(e=='+')
return a+b;
else if(e=='-')
return a-b;
else if(e=='*')
return a*b;
else if(e=='/')
return a/b;
else
{
cout<<"error!"<<endl;
return 100;
}
}
void precede(stack1 &S1,stack2 &S2,char ch,char p[][N])
{
//cout<<"11111111111"<<endl;
char e;
int a,b,c,flag=1;
if(S1.top==S1.base)
{
push1(S1,ch);
flag=0;
}
//cout<<p[i][j]<<" ";
//p[i][j];
while(flag!=0)
{
int i=verify(*(S1.top-1));
int j=verify(ch);
//cout<<"333"<<endl;
if(S1.top==S1.base)
{
// cout<<"8888"<<endl;
push1(S1,ch);
flag=0;
}
else
{
if(p[i][j]=='>')//栈顶>ch
{
// cout<<"sssssss"<<endl;
pop1(S1,e);//运算符出栈
pop2(S2,a);
pop2(S2,b);
// cout<<"a="<<a<<" b="<<b<<" e="<<e<<endl;
// if(e=='(')
// cout<<"i="<<i<<" j="<<j<<" ch="<<ch<<endl;
c=judge(b,e,a);//计算
// cout<<c<<endl;
c=c+48;
push2(S2,c);//入栈
// cout<<"S2.top="<<*(S2.top-1)<<endl;
// cout<<"okok!"<<endl;
}
else if(p[i][j]=='<')
{
// cout<<"eeeeeee"<<endl;
push1(S1,ch);//入栈: top<ch
flag=0;
// cout<<"dddd"<<endl;
}
else if(p[i][j]=='=')
{
// cout<<"[[[[[[[[]]]]]]]]"<<endl;
pop1(S1,e); //出栈
flag=0;
// cout<<"fffffffff"<<endl;
}
else
cout<<"predede error!"<<endl;
}
// cout<<*(S2.top-1)<<endl;
// cout<<"S1.top="<<*(S1.top-1)<<endl;
}
}
void final(stack1 &S1,stack2 &S2)
{
int a,b,c;
char e;
pop1(S1,e);
pop2(S2,b);
pop2(S2,a);
// cout<<a<<e<<b<<endl;
c=judge(a,e,b);
// cout<<c<<endl;
c=c+48;
// cout<<c<<endl;
push2(S2,c);
}
int main()
{
stack1 S1;
stack2 S2;
init1(S1);
init2(S2);
string S;
cin>>S;
char p[N][N];//存储优先级关系
for(int i=0;i<5;i++)
for(int j=0;j<6;j++)
{
cin>>p[i][j];
}
for(int i=0;S[i]!='\0';i++)
{
// cout<<"4444444"<<endl;
if(S[i]>='0'&&S[i]<='9')//是数字
{
push2(S2,S[i]);//入操作数栈
// cout<<"22222222"<<endl;
}
else//是字符
{
//如果top<ch,ch入栈;如果top>ch,弹出top,弹出两个操作数,进行计算,结果压入操作数栈;
//如果=,弹出栈顶
//cout<<S1.top<<endl;
// cout<<"jjjj"<<endl;
precede(S1,S2,S[i],p);//存在死循环
// cout<<"????"<<endl;
}
}
while(S1.base!=S1.top)//栈不空
{
final(S1,S2);
}
//cout<<"finally!"<<endl;
cout<<*(S2.top-1);
}
运行说明:
输入的时候,先输入一个式子,
然后,输入下面的符号(直接复制粘贴即可):
>><<<>
>><<<>
>>>><>
>>>><>
<<<<<=
输入这些玩意的主要原因呢是因为——代码中考虑运算符优先级的时候,将不同运算符之间的优先级关系存在了一个二维数组里!
咱们输入的这堆东西,就是二维数组存储的内容!