问题分析: 输入一个代数表达式, 表达式只能含有“+”, “‐”, “*”, ”/”,(,),1,2,3,4,5,6,7,8,9,0
字符且每个数字均小于 10, 设表达式除括号匹配有误外无其它错误。 编写算法对输入的表
达式进行检测, 判断括号匹配是否正确。 如果对于输入的表示能按照正确的优先级将最终结
果求出那么表达式肯定是正确的。 而如果要求出最终结果, 效率会低, 那么对运算过程进行
简化, 按照所给的表达式推导出最终可以求出结果那么表达式肯定是正确的, 括弧肯定匹配。
数学模型: 模拟手算过程, 用栈作为存储结构约定优先级。 Stack S,OP; S 存储运算符, OP
存储参与运算的数字。 遇到‘(’、 数字, 时直接压入相应的栈中, 当遇到+、 ‐、 *、 /操作符
是先把栈 S 中的栈顶元素取出比较相应的优先级, 若当前操作符的优先级低与栈顶的则进行
一次运算。 由于问题要求的是单位数而进行相应的运算后可能会变成小数, 或多位数, 若对
其进行处理会麻烦, 则默认运算后结果是 1, 将以压入相应的栈中。 若在运算过程中不能进
行或不可操作则说明表达式不正确。
所发策略的选择 采用蛮力法, 从右向左处理表达式一旦出现错误的情况直接输出不匹配
程序实现:
void CPepeiDlg::OnCancel()
{ flag=0; UpdateData(true);
S.InitStack();OP.InitStack();
char e; int m=m_strin.GetLength();
for(int i=0;i<m;i++) //从表达式中着个取字符
{ switch(m_strin[i])
{case '(': //有括弧直接进栈
S.Push(m_strin[i]); break;
case '0': case '1':
case '2': case '3':
case '4': case '5':
case '6': case '7':
case '8': case '9': //如果是操作数直接进栈
OP.Push(m_strin[i]); break;
case '+':
case '‐':
e=S.GetTop();
if(e=='('||e=='a') //运算符栈顶是‘(’ 或空进栈
S.Push(m_strin[i]);
else
{ //栈顶运算符的优先级比‘+’, ‘‐’ 高
JiSuan(); //从栈中取出元素计算
S.Push(m_strin[i]); }
break;
case '*':
case '/':
e=S.GetTop();
if(e=='('||e=='a'||e=='+'||e=='‐')
S.Push(m_strin[i]); //栈顶运算符优先级比‘*’, ‘/’ 低则进栈
else //栈顶运算符优先级比‘*’, ‘/’ 高
{ JiSuan();
S.Push(m_strin[i]); } break;
case ')': //当前操作数是‘)’
e=S.GetTop();
if(e=='a'||e=='(') //栈顶为空或‘(’ 则表达是有误
{ MessageBox("表达式有错误! ");
return;}
while(e!='(') //取栈顶的操作数进行运算知道取出‘)’
{
JiSuan();
e=S.GetTop();
} S.Pop(); //将‘(’ 出栈
}
if(flag) return;
} //检验栈中的运算符和操作数是否符合标准
while(S.StackEmpty()==1) //栈不空进行计算
JiSuan();
OP.Pop(); //若表达式正确最后操作数栈中还有一个元素, 将其出栈
if(S.StackEmpty()==0&&OP.StackEmpty()==0)
{ MessageBox("输入表达式正确! ");
return;}
else
{ MessageBox("输入表达式错误! ");
return;}
}
void CPepeiDlg::JiSuan()
{ char a,b,c;
if(S.StackEmpty()==0)
{ MessageBox("输入有误! ");
flag=1; return;} //c 存放运算符
c=S.GetTop(); S.Pop();
if(OP.StackEmpty()==0)
{ MessageBox("输入有误! ");
flag=1; return; }
a=OP.GetTop(); OP.Pop(); //a 存放操作数
if(OP.StackEmpty()==0)
{ MessageBox("输入有误! ");
flag=1; return;}
b=OP.GetTop(); OP.Pop(); //b 存放操作数
OP.Push(1); //将计算结果默认为 1 将 1 压入操作数栈
}