又一个月过去了,翘了不少课,可是实验还是得做啊....
这个是上上周的实验三,堆栈模拟计算器的,书上有伪代码,不想看,参考了黄建的,写成这样了:
实 验 三
利用堆栈的基本操作来实现中缀表达式的计算。该中缀表达式中包括:+、-、*、/、(、)和整数。
提示:首先要检查该表达式是否合法,然后计算。
示例:
输入:10 + (4 – 20 *) / 4
输出:表达式错误
输入:10 + (20 - 10) / 5 * 2
输出:14
写了两个栈,一个数据栈,一个符号栈。。。
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;
typedef struct
{
double *data;
int top;
}nstack;
typedef struct
{
char *data;
int top;
}cstack;
nstack num;
cstack op;
char suffix[1010],s[1010];
double num1,num2,num3;
void init(nstack &s)
{
s.data=new double [100];
s.top=-1;
}
void init(cstack &s)
{
s.data=new char [100];
s.top=-1;
}
bool empty(nstack s)
{
if(s.top==-1)
return 1;
return 0;
}
bool empty(cstack s)
{
if(s.top==-1)
return 1;
return 0;
}
bool top(nstack s,int &e)
{
if(s.top==-1)
return 0;
e=s.data[s.top];
return 1;
}
bool top(cstack s,char &e)
{
if(s.top==-1)
return 0;
e=s.data[s.top];
return 1;
}
bool pop(cstack &s,char &e)
{
if(s.top==-1)
return 0;
e=s.data[s.top--];
return 1;
}
bool pop(nstack &s,double &e)
{
if(s.top==-1)
return 0;
e=s.data[s.top--];
return 1;
}
void push(cstack &s,char e)
{
s.data[++s.top]=e;
}
void push(nstack &s,double e)
{
s.data[++s.top]=e;
}
int opmember(char c)
{
if(c=='+'||c=='-'||c=='*'||c=='/')
return 1;
if(c=='(')
return 2;
if(c==')')
return 3;
return 0;
}
int getpre(char c)
{
if(c=='#') return -1;
if(c=='(') return 0;
if(c=='+'||c=='-') return 1;
if(c==')') return 2;
if(c=='*'||c=='/') return 2;
}
bool compare(char s1,char s2)
{
if(getpre(s1)>=getpre(s2))
return 1;
return 0;
}
bool isnum(char c)
{
if(c>='0'&&c<='9') return 1;
return 0;
}
bool islogic(char *s)
{
int len=strlen(s);
int l=0,r=0;
if(opmember(s[0]==1||opmember(s[0])==3)) return 0;
if(opmember(s[len-1])==1||opmember(s[len-1])==2) return 0;
for(int i=0;i<len-1;i++)
{
if(s[i]=='(') l++;
if(s[i]==')') r++;
if(opmember(s[i])==3&&isnum(s[i+1])) return 0;
if(opmember(s[i])==1&&opmember(s[i+1])==1) return 0;
if(opmember(s[i])==1&&opmember(s[i+1])==3) return 0;
if(opmember(s[i])==2&&opmember(s[i+1])==3) return 0;
if(opmember(s[i])==3&&isnum(s[i+1])) return 0;
if(isnum(s[i])&&opmember(s[i+1])==2) return 0;
if(s[i]=='/'&&s[i+1]=='0') return 0;
}
if(s[len-1]==')') r++;
if(l!=r) return 0;
return 1;
}
double operate(double a,char op,double b)
{
if(op=='+') return a+b;
else if(op=='-') return a-b;
else if(op=='*') return a*b;
else if(op=='/') return a/b;
}
void transform(char *suffix,char *s)
{
init(op);
push(op,'#');
int i=0,k=0;
char ch=s[0],c;
while(!empty(op))
{
if(isnum(ch)) suffix[k++]=ch;
else
{
suffix[k++]=' ';
switch(ch)
{
case '(':push(op,ch);break;
case ')':
{
pop(op,c);
while(c!='(')
{
suffix[k++]=c;
pop(op,c);
}
break;
}
default:
{
while(top(op,c)&&(compare(c,ch)))
{
suffix[k++]=c;pop(op,c);
}
if(ch!='#')
push(op,ch);
break;
}
}
}
if(ch!='#') {i++;ch=s[i];}
}
suffix[k]=='\0';
}
void calculate()
{
init(num);
int len=strlen(suffix),i=0;
while(i<len)
{
if(suffix[i]==' ')
{
i++;continue;
}
else if(suffix[i]=='#')
break;
else
{
double cur=0;
bool hasnum=0;
while(isnum(suffix[i]))
{
cur*=10;
cur+=suffix[i++]-'0';
hasnum=1;
}
if(hasnum)
push(num,cur);
if(suffix[i]==' ')
{
i++;continue;
}
if(opmember(suffix[i])==1)
{
pop(num,num1);
pop(num,num2);
num3=operate(num2,suffix[i++],num1);
push(num,num3);
}
}
}
double ans;
pop(num,ans);
printf("%.2lf\n",ans);
}
int main()
{
while(scanf("%s",s)!=EOF)
{
memset(suffix,0,sizeof(suffix));
int len=strlen(s);
if(!islogic(s))
cout<<"表达式错误!\n";
else
{
s[len]='#';
transform(suffix,s);
calculate();
}
}
return 0;
}