表达式求值

 几年之前因为一个表达式求值方面的问题烦恼了好几天。最终问题虽然解决了,但对于表达式求值的实现却未理解。大概是因为当初数据结构基础薄弱的缘故吧。好几年了,今天偶尔想起,决定写一个。虽说写,也不是原创,而是在别人的基础上修改而来的。放在这里,以备查阅。

首先是exprcalc.h文件

#ifndef _EXPR_CALC_H_
#define  _EXPR_CALC_H_

#include 
< stack >
#include 
< string >
#include 
< exception >

#pragma  warning(disable: 4018 4244)

template
< class  T >
class  ExprCalc
{
public:
    ExprCalc(std::
string expr) : expr_(expr) { }
    
void SetExpr(std::string expr) { expr_ = expr; }
    T Resolve();

private:
    
// 处理栈内的元素
    void Deal()
    
{
        
char sign = op_.top(); op_.pop();
        T x 
= num_.top(); num_.pop();
        T y 
= num_.top(); num_.pop();
        T res 
= Calc(y, x, sign); num_.push(res);
    }


    
// 计算x sign y, 结果返回,sign= +、-、*、/
    T Calc(T x, T y, char sign) 
    
{
        
switch (sign)
        
{
        
case '+'return x + y;
        
case '-'return x - y;
        
case '*'return x * y;
        
case '/'return x / y;
        
defaultthrow std::logic_error("Invalid Expression!");
        }

    }


    
// 计算符号的优先级
    int Prior(char sign) 
    
{
        
if (sign == '*' || sign == '/' || sign == '%')  return 2;
        
if (sign == '+' || sign == '-')  return 1;
        
return 0;
    }


private:
    std::
string      expr_;     //输入的字符串
    std::stack<T>    num_;      //数据栈
    std::stack<char> op_;       //符号栈
}
;

template
< class  T >
T ExprCalc
< T > ::Resolve()
{
    
if (expr_.length() == 0
        
throw std::logic_error("Invalid Expression!");

    
for (int i = 0; i < expr_.length(); )
    
{
        
// 第一个数是负数,或(-8+9)这种情况
        if ((expr_[i] >= '0' && expr_[i] <= '9'|| 
            (expr_[i] 
== '-'&& (i == 0 || expr_[i-1== '('))
        
{
            
int j = 0;
            
char operand[10= {0, }
            
while ((expr_[i] >= '0' && expr_[i] <= '9'|| 
                (expr_[i] 
== '-' && (i == 0 || expr_[i-1== '(')) || 
                (expr_[i] 
== '.'))
                operand[j
++= expr_[i++];
            T num 
= atof(operand);
            num_.push(num);
        }

        
else
        
{
            
if (expr_[i] == ')'
            
{
                
while (op_.top() != '('
                    Deal(); 
                op_.pop();
            }

            
else 
            
{
                
if (!op_.empty() && expr_[i] != '(' &&
                    Prior(expr_[i]) 
<= Prior(op_.top()))
                    Deal();
                op_.push(expr_[i]);
            }

            i
++;
        }
            
    }


    
while (!op_.empty())
        Deal();

    T res 
= num_.top(); num_.pop();
    
return res;
}


#endif

 然后是exprcalc.cpp文件

#include  " ExprCalc.h "
#include 
< iostream >
using   namespace  std;

int  main()
{
    
try
    
{
        ExprCalc
<int> ec("2*(25+25)+100*500");
        cout 
<< ec.Resolve() << endl;
    }

    
catch (const exception& e)
    
{
        cout 
<< e.what() << endl;        
    }


    
return getchar();
}

此程序在vs2005下测试通过。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值