最近为家人做了一个简单的财物系统
其中涉及到金额的输入,为了方便不仅可以输入数据,而且可以对数学表达式求值
方法一:
将表达式由中缀表达式转化为后缀表达式,然后利用栈进行计算
比如我有表达式2-(3+4*5)/6 转化为后缀表达式为:2#3#4#5#*+6#/- ,#号是用来区别数字
遍历后缀表达式,只要把数字压栈,如果是运算符则pop两次进行运算后把结果压栈,最后在栈内的就是所要的结果。
前缀转后缀的算法是:
定义一个栈stack用来存放运算符,
//遍历中缀运算符,
{
if 是数字,则在后面加上字符'#';
else 是运算符
{ //判断stack是否为空
if(是空)把运算符入栈;
else if (运算符为+或者-)把栈中的运算符出栈并加到数字的后面,直到栈顶的运算符为‘(’或栈空;
else if(为*或/ )栈顶为+或-, 则入栈;为:*或/ 则把栈顶出栈,加到后缀表达式上,把当前运算符入栈;如果是(,则入栈;
else if (为'(' )入栈
else if(为')')则把栈中的运算符依次出栈,直到栈顶为'('或栈空 //记得最后要把'('出栈
}
方法二:直接利用栈计算
Evaluate()
{
InitStack( OPTR ); Push( OPTR, '#' );
InitStack( OPND ); c = getchar();
while( c!='#' || GetTop( OPTR )!='#' )
{
if( !In( c, OP ) ) { Push(( OPND, c ); c = getchar() ; } //不是运算符则入栈
else
{
switch( Precede( GetTop( OPTR ), c ) )
{
case '<': //栈顶的优先级低
Push( OPTR, c );
c = getchar();
break;
case '=': //脱括号并接受下一个字符
Pop( OPTR, x );
c = getchar();
break;
case '>': //退栈并将运算结果入栈
Pop( OPTR, theta );
Pop( OPND, b ); Pop( OPND, a );
Push( OPND, Operate( a, theta, b ) );
break;
}
}//else
}//while
return GetTop( OPND );
}
方法一是自己总结的,并且我已经用c#和javascript实现了,能实现小数点的计算,如果还有什么需要改进的地方,
大家可以提出建议;
方法二则是翻阅《数据结构》一书是发现的,所以思路很清晰,我用C++实现了,这里我照炒算法,不知道有没有侵犯版权。。。