返回列表 发帖

一个计算四则表达式的模板

在9月8日那天我特意编写的,给大家分享的,
& I$ w" \+ s( r0 C& N一个很方便的函数模板,可以并且只可以计算含括号的四则表达式" d5 C9 Q: x) {+ D
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
2 A) |# w+ g% e8 J2 x参数解释:9 ^$ }# a, T  P8 m; R
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
6 e3 P3 B% R) f5 Z, j. @nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定6 Z& K0 t  b* [3 b2 r1 G
返回值:4 ]9 x/ b$ n' _8 d! v5 F
返回非0表示计算成功,0表示计算失败有错误
) V1 D% X  r4 {1 E7 v! j' r
$ T7 k% @$ ^6 e: z( N) r. P 0 o! _: P. o' a. ?

( d9 U+ e3 m" X8 P2 E1 p$ V程序代码:
' d( c% ^2 L0 d: `; K, A# `
6 G* e9 M/ I: R, p% knamespace fy_Exp{% Q% A) h( U$ s( N9 G
namespace {template <class _T>
9 j. e3 c4 V7 X8 s2 V: y! K  ~inline _T GetExpValue(_T t[], char& csym){
( M. T( ?- g7 E- }! k; \    char c=csym; csym=0;& c0 [( g7 n% `7 z) h+ y# ~
    switch(c){: c; {& ]* `5 Q' a% _
    case '+':return t[0] += t[1];
9 ^: q& x- p1 M    case '-':return t[0] -= t[1];
& s+ o0 q" G. B$ m6 b7 z4 b3 C    case '*':return t[0] *= t[1];
% i/ ?! {4 N$ u7 T5 E1 Y    default: return t[0] /= t[1];//case '/':" v  E, C: a; X4 f) i2 `
    }
' b$ z4 R' G2 @5 f6 K! @6 G! `0 m5 b  L}}# e. }8 J9 n, @' G9 N7 H* D! a) d
template <class _T, class _Tstream>
# E& ~- u+ Q- X' E1 `/* _Tstream: inputstream, _T: get return value
9 N0 E$ L# [( j- D) o* Return nonzero if get value successfully */: s, H8 @! |" Q8 F  T3 O( \  @2 a9 @
int GetExpValue(_Tstream& istrin, _T& nReturn){6 t; i; M; f, d% S! x/ \
    _T t[3] = {0}; //雨中飞燕之作
5 U  g/ l) D- {9 q: \0 ^    char csym[3] = "++";/ l. K% }' j% w% q
    int nLevel = 1, nERR = 0;
( Q6 h9 v, E& ]+ x' z, [2 f    if(!(istrin>>t[1]))istrin.clear();
$ x2 t+ x: D: M4 o    for(;;){
0 B" J! L. s1 T2 l& }, D        if(istrin>>csym[2]){7 Q" e( p5 w# b! t/ {# I
            switch(csym[2]){% {( Z6 o1 [: i3 c; k/ |6 E* P; K
            case '(':
, `1 Y# j2 o/ m                if(!csym[1]){nLevel=0x100; nERR=1;}else8 y( g' Y( o2 s! U  H* i- c1 _
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
; e% y8 N/ C4 D6 b+ c) p. z/ J                else{nLevel=0x100; nERR=1;}* I1 I7 A* K& |' n& C1 P
                break;
2 K( Y; w% s, K; Y' T            case ')':
- L/ f4 q% H8 _* i$ n                {nLevel = 0x100;}break;* }; o3 w3 n/ `
            case '+':case '-':case '*':case '/':' Z! m" T! d2 O' j' n2 f
                {csym[nLevel++] = csym[2];}break;' u* E. B( \/ K# N( i
            case ' ':case '\r':case '\n':case '\t':continue;$ W9 k( ]+ t/ b8 m4 x
            default:) Y8 d7 S7 ~$ b# i  [# ?
                {nLevel=0x100; nERR=1;}: T+ e5 Z3 x; M3 j  t* j5 l
            }
. N7 p6 M6 ~7 _7 n: [6 Q1 {  X            if(nLevel==0x100)break;, b8 K3 l2 ]: ?$ F
            if(nLevel&0x10 || istrin>>t[2]){
6 G0 u' ^5 W. E  R! ], a8 |$ s- I                nLevel &= 0xF;: w% c# i" a- L5 q& B
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
( P6 b! t9 j# T: @; H6 d                if(csym[1]=='*'||csym[1]=='/'){* o7 F2 {3 J* E3 v
                    GetExpValue(t+1, csym[1]);7 \' e; h& Y- p( S- a( q
                }
7 C0 f5 }- @7 i$ f9 q, |6 Q3 Y                else{# t7 _# _! J# f3 q5 Q$ C* ]- h- a
                    GetExpValue(t, csym[0]);( c( W5 l2 r0 _( W0 X2 w8 S
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;, E  \. k  g, ^. ~  ^
                }
& K% E6 Z! L" g; N/ \: d                nLevel = 1;+ q, m: E3 s3 V7 m9 t# t& N
            }
& P% t2 }+ I& s& A" e2 e            else istrin.clear();% D$ e( I1 w9 _4 l( ^" s9 `# l
        }2 Y% ~- t- K% ?  D1 D
        else{nERR = -1; break;}* t; s& e' b1 H
    }, o, W' O5 `& S# d4 [
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
2 z1 m* z1 V0 a- K    else nReturn=GetExpValue(t, csym[0]);
$ `% G9 [8 p3 G$ D0 i, m9 H    return nERR==-1?1:0;) N7 P" E2 @4 e6 `
}}/ i+ p# [3 p+ n+ L, I0 u

) l* N1 u- s: q, h; L( `2 |* [" v2 o: ^
; f& K: {8 C, W: d/ ?( N" z* k
函数模板使用示例:
0 a3 n( E8 N+ G: R0 T7 x; H1 M" h8 M在以上那段代码的后面加上以下代码:( }, G0 J  l' E
" u; H7 k) j1 Q

# Y# U! ~- r! d1 Z( }! q
$ Y% q: Q: R, |4 u$ N1 q1 ^+ Q程序代码:
- s: \- [% H$ x6 q
) A" Q! }0 S9 v: s: g1 b#include<strstream>* X4 z( z9 ~  V2 ]0 c2 Y* v) A
#include<iostream>6 d: ]# N2 i# h$ I0 w* K
#include<string>
; T2 _, u6 ?* J- z- Cusing namespace std;3 V5 i1 p- t! \6 Q# }1 U& L& X# c* X
int main(void)6 G* l& \4 A0 Q& a0 K
{: H1 l, Z# J& M* o# L: i) _; e
    string s1;
+ l* |; A+ T- @5 M7 F& U) {$ ^    while(cin>>s1)6 d  E2 j" R+ k+ b
    {
+ X- O9 Y  W! w- {        istrstream isin(s1.data());
, r& x+ A- p6 I9 D# F        double d;
7 D3 Q7 m0 H9 I. z  N+ a        if(fy_Exp::GetExpValue(isin, d))* J1 [( B  H# ]: R+ M& ?/ l9 I
        {
' i1 T/ I& Z$ G, Y3 W  h            cout<<d<<endl;
' Y+ e9 w: x. ^1 D* e        }- m* F9 ?* d0 c! _
        else/ P+ j# Z7 O  s' g% D7 {' `
        {
6 R  j: a% P& i( P! T* Y, z            cout<<"ERROR"<<endl;, r+ T8 |# ~! W. p, g: {- z1 F
        }
9 V# [' m1 @. E3 v* e0 `    }
! x! U& C) z; x+ A4 ^    return 0;
0 z: ?$ \8 _* S8 E; \* i" Q' U}
. ~3 p" q9 C' f% f4 p% d
- N' k! j# a( v7 d$ z3 D/ a( c7 l  P6 L" z9 e3 \" l
然后编译执行就可以了(*^_^*): ~$ _$ {" |( q/ ^. n
其它:TC++上一定编译错误,不保证在VC6上也能通过编译+ p) f& ~2 p6 V, o: U; Z
      建议使用VC7或VC更高版本,或者使用GNU C++编译

返回列表
【捌玖网络】已经运行: