借助堆栈实现的四则运算的源代码。输入一个字符串,可以计算值。 支持加减乘除、小数点、括号。 #pragma once #include <string> #include <iostream> #include <stack> #include <string> #include <assert.h> #include <exception> using namespace std; namespace utility { /// 异常定义类 class bad_expression : public std::exception { public: bad_expression(){} virtual const char * what() const{ return "bad expression"; } }; namespace detail{ struct opdata { opdata(){} opdata( char v ) : op(v), is_op(true){} opdata( double v ) : val(v), is_op(false){} bool is_op; union{ double val; char op; }; }; inline double pop_value( std::stack<opdata>& op ) { if( op.top().is_op ) throw bad_expression(); double c=op.top().val; op.pop(); return c; } /// 弹出栈并计算,直到碰到 '(' 或者栈底 static void calculate( std::stack<opdata>& op, double& v, bool addsub=true ) { while( !op.empty() ){ opdata o=op.top(); if( o.is_op ){ switch( o.op ){ case '(': return; case '+': if( !addsub ) return; // 如果 addsub=false 不计算 + op.pop(); v=pop_value(op)+v; break; case '-': if( !addsub ) return; // 如果 addsub=false 不计算 - op.pop(); v=pop_value(op)-v; break; case '*': op.pop(); v=pop_value(op)*v; break; case '/': op.pop(); v=pop_value(op)/v; break; case '.': op.pop(); v=v / ( pow( 10, int( log10(v) )+1 ) +pop_value(op); break; default: throw bad_expression(); } }else{ if( v!=0 ) throw bad_expression(); v=o.val; op.pop(); } } } } static double calculate( const std::string& expr ) { using namespace detail; //the operation value std::stack< opdata > opv; double v=0; for( auto i=expr.cbegin(); i!=expr.cend(); ++i ){ char c=*i; if( ( c>='0' ) && ( c<='9' ) ){ c=c-'0'; v=v*10+c; }else if(')'== c){ // 计算 calculate( opv, v ); if( opv.top().op!='(' ) throw bad_expression(); opv.pop(); }else if( '('==c ){ opv.push( c ); }else if( '+'==c || '-'==c ){ calculate( opv, v ); opv.push(v); opv.push( c ); v=0; }else if( '*'==c || '/'==c ){ calculate( opv, v, false ); opv.push(v); opv.push(c); v=0; }else if( '.'==c ){ opv.push(v); opv.push(c); v=0; }else{ throw bad_expression(); } } calculate( opv, v ); return v; } }; 测试: using namespace utility; std::string a = "-4-(33*2-7)*2/(9-4.7)+(-8)"; std::cout << a << std::endl; std::cout << calculate(a) << std::endl;