表达式的计算
程序员文章站
2024-02-26 19:06:46
...
要求:
按常规形式输入算术表达式(例如:输入2*(6-4)+8/4),要求能够:
⑴生成表达式的前缀、后缀表示,并输出;
⑵基于表达式的前缀、后缀、中缀表示,对该表达式求值;
⑶编写一个主程序对表达式求值函数进行测试。
请本校学弟学妹不要抄我的代码当数据结构作业,这对其他同学是非常不公平的
#include<bits/stdc++.h>
#define Max_size 100
using namespace std;
typedef struct
{
char elem[Max_size];
int length;
}CharStack;
typedef struct
{
int elem[Max_size];
int length;
}IntStack;
int index (char c)
{
if (c=='+') return 0;
else if (c=='-') return 1;
else if (c=='*') return 2;
else if (c=='/') return 3;
else if (c=='(') return 4;
else if (c==')') return 5;
else
return 6;
}
int value[7][7]={{1,1,-1,-1,-1,1,1},
{1,1,-1,-1,-1,1,1},
{1,1,1,1,-1,1,1},
{1,1,1,1,-1,1,1},
{-1,-1,-1,-1,-1,0,0},
{1,1,1,1,0,1,1},
{-1,-1,-1,-1,-1,0,0}};
void initialoptr(CharStack &s)
{
s.length=0;
}
void initialopnd(IntStack &s)
{
s.length=0;
}
void push_optr(CharStack &s,char c)
{
s.elem[s.length++]=c;
}
void push_opnd(IntStack &s,int n)
{
s.elem[s.length++]=n;
}
char pop_optr(CharStack &s)
{
return s.elem[--s.length];
}
int pop_opnd(IntStack &s)
{
return s.elem[--s.length];
}
char get_optr(CharStack s)
{
return s.elem[s.length-1];
}
int cal(int a,int b,char c)
{
int sum;
switch (c){
case '+':sum=a+b;break;
case '-':sum=a-b;break;
case '*':sum=a*b;break;
case '/':sum=a/b;break;
}
return sum;
}
int Calmiddle(string s)//中缀 计算
{
CharStack optr;
IntStack opnd;
initialoptr(optr);
initialopnd(opnd);
push_optr(optr, '#');
char topoptr, c;
int num = 0, a, b, i = 0;
topoptr = get_optr(optr);
while(s[i] != '#' || topoptr != '#')
{
if (s[i] >= '0' && s[i] <= '9')
{
num = 0;
while (s[i] >= '0' && s[i] <='9')
{
num = num * 10 + s[i] -'0';
i++;
}
push_opnd(opnd, num);
}
else
{
if (value[index(get_optr(optr))][index(s[i])] == 1)
{
c = pop_optr(optr);
b = pop_opnd(opnd);
a = pop_opnd(opnd);
push_opnd(opnd, cal(a, b, c));
}
else if(value[index(get_optr(optr))][index(s[i])] == 0)
{
c = pop_optr(optr);
i++;
}
else
push_optr(optr, s[i++]);
}
topoptr = get_optr(optr);
}
return pop_opnd(opnd);
}
int CalPrefix(string s)//前缀计算
{
IntStack opnd;
initialopnd(opnd);
int length = s.length()-1, a, b, num;
while(length >= 0)
{
if (s[length] >='0' && s[length] <= '9')
{
int k = 1;
num = 0;
while(s[length] >= '0' && s[length] <= '9')
{
num = num + k * (s[length--] - '0');
k = k * 10;
}
push_opnd(opnd, num);
}
else
{
a=pop_opnd(opnd);
b=pop_opnd(opnd);
push_opnd(opnd, cal(a, b ,s[length--]));
}
length--;
}
return pop_opnd(opnd);
}
int Calpostfix(string s)//后缀计算
{
IntStack q;
initialopnd(q);
int i = 0, a, b, num = 0;
while(i<s.length())
{
if(s[i]>='0'&&s[i]<='9')
{
num = 0;
while(s[i] >= '0' && s[i] <= '9')
{
num = 10 * num + s[i++] - '0';
}
push_opnd(q,num);
}
else
{
b=pop_opnd(q);
a=pop_opnd(q);
push_opnd(q,cal(a,b,s[i++]));
}
i += 1;
}
return pop_opnd(q);
}
string Postfixexp(string s)//中转后
{
string suffix = "";
CharStack optr;
initialoptr(optr);
push_optr(optr,'#');
for(int i=0,j=0;i<s.length();)
{
if(s[i]>='0'&&s[i]<='9')
{
while(s[i] >= '0' && s[i] <= '9')
{
suffix = suffix + s[i++];
}
suffix = suffix + ' ';
}
else
{
while (value[index(get_optr(optr))][index(s[i])]==1)
{
suffix = suffix + pop_optr(optr);
suffix = suffix + ' ';
}
if(value[index(get_optr(optr))][index(s[i])]==0)
{
pop_optr(optr);
i++;
}
else
push_optr(optr,s[i++]);
}
}
while (get_optr(optr) != '#')
{
suffix = suffix + pop_optr(optr) +' ';
}
return suffix;
}
string Prefixexp(string s)//zhong qian
{
string prefix = "";
CharStack p,q;
initialoptr(p);
initialoptr(q);
push_optr(p,'#');
push_optr(q,'#');
for (int i=s.length()-1;i>=0;)
{
char c = s[i];
if(s[i]>='0'&&s[i]<='9')
{
while(s[i] >= '0' && s[i] <= '9')
{
c = s[i];
push_optr(q, s[i--]);
}
push_optr(q,' ');
}
else
{
while(value[index(s[i])][index(get_optr(p))]==-1)
{
push_optr(q,pop_optr(p));
push_optr(q,' ');
}
if (value[index(s[i])][index(get_optr(p))]==0)
{
pop_optr(p);
i--;
}
else
push_optr(p,s[i--]);
}
}
while(get_optr(p) != '#')
{
push_optr(q,pop_optr(p));
push_optr(q,' ');
}
while(get_optr(q) != '#')
{
prefix = prefix + pop_optr(q);
}
return prefix;
}
int main()
{ string s,s1,h,suffix,prefix,q;
printf("请输入一个中缀表达式: \n");
getline(cin,s1);
suffix=Postfixexp(s1);
cout<<"后缀表达式为"<<suffix<<endl;
prefix=Prefixexp(s1);
cout<<"前缀表达式为"<<prefix<<endl;
printf("请输入一个后缀表达式: \n");
getline(cin,h);
printf("结果为%d\n",Calpostfix(h)) ;
printf("请输入一个前缀表达式: \n");
getline(cin,q);
printf("结果为%d\n",CalPrefix(q));
printf("请输入一个中缀表达式(#号结束): \n");
getline(cin,s);
printf("结果为%d\n",Calmiddle(s));
return 0;
}