我使用堆栈来评估表达式。 最重要的功能如下:
double Expression_Eval()
{
SeqStack<char,100> OPTR;
SeqStack<double,100> OPND;
OPTR.Push('@');
char ch;
ch=getchar();
while (ch!='@' || OPTR.GetTop()!='@')
{
if (!InOPTR(ch))
{
int n=ch-'0';
double num=(double)n;
OPND.Push(num);
ch=getchar();
}
else
{
char pre_op=OPTR.GetTop();
switch (Precede(pre_op, ch))
{
case '<': OPTR.Push(ch);
ch=getchar();
break;
case '=': OPTR.Pop();
ch=getchar();
break;
case '>': double b=OPND.Pop();
double a=OPND.Pop();
pre_op=OPTR.Pop();
OPND.Push(Operate(a, pre_op, b));
ch=getchar();
break;
}
}
}
return OPND.GetTop();
}
然后,当我输入 8 /(5-3)@ 时,它不会打印结果。
我认为循环终止条件 ch!='@'|| OPTR.GetTop()!='@'是错误的。 当我按 Enter 时,getchar()获取最后一个字符 CR 但不是 @ 。
但是,我不知道如何修改它以使我的程序正常工作。
我的计划的另一部分如下:
#include<iostream>
using namespace std;
template<typename DataType,int StackSize>
class SeqStack
{
private:
DataType data[StackSize];
int top;
public:
SeqStack()
{ top=-1; }
~SeqStack() {}
void Push(DataType x)
{
if(top == StackSize-1)
throw "error";
data[++top]=x;
}
DataType Pop()
{
if(top == -1)
throw "error";
DataType x=data[top--];
return x;
}
DataType GetTop()
{
if(top != -1)
return data[top];
else
cout<<"error";
}
};
bool InOPTR(char ch)
{
if( (ch>='(' && ch<='+') || ch=='-' || ch=='/' )
{
return true;
}else{
return false;
}
}
char Precede(char op1, char op2)
{
char pri[7][7]={ {'>','>','<','<','<','>','>'}
, {'>','>','<','<','<','>','>'}
, {'>','>','>','>','<','>','>'}
, {'>','>','>','>','<','>','>'}
, {'<','<','<','<','<','=','@'}
, {'>','>','>','>','@','>','>'}
, {'<','<','<','<','<','@','='} };
int m,n;
switch(op1)
{
case '+': m=0;break;
case '-': m=1;break;
case '*': m=2;break;
case '/': m=3;break;
case '(': m=4;break;
case ')': m=5;break;
case '@': m=6;break;
}
switch(op2)
{
case '+': n=0;break;
case '-': n=1;break;
case '*': n=2;break;
case '/': n=3;break;
case '(': n=4;break;
case ')': n=5;break;
case '@': n=6;break;
}
return pri[m][n];
}
double Operate(double a, char op, double b)
{
double result;
switch(op)
{
case '+': result=a+b; break;
case '-': result=a-b; break;
case '*': result=a*b; break;
case '/': result=a/b; break;
}
return result;
}
int main()
{
double r=Expression_Eval();
cout<<r<<endl;
return 0;
}
答案 0 :(得分:2)
问题似乎是&#39; @&#39;被认为是一个数字,但它应被视为一个操作:
使用:
bool InOPTR(char ch) {
if ((ch >= '(' && ch <= '+') || ch == '-' || ch == '/' || ch=='@'){
return true;
}
else {
return false;
}
}
请注意&#39; @&#39;是ASCII 64,这不包括在牧场&#39;(&#39;到&#39; +&#39; [40-43]
希望这有帮助。
答案 1 :(得分:0)
按下回车键后,您需要在getchar();
之后使用回车符或换行符。
一个技巧如下。
ch=getchar();
getchar(); //this getchar to consume CR.
由于您多次使用ch = getchar()
,因此必须在许多地方使用上述解决方案。
更好地解决此问题的方法是enter string
,而不是使用getchar()
输入单个字符...
希望你得到我想说的话......