返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
. b4 |+ o9 z2 R- m一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
: l4 n2 \2 f8 A$ V" s只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
9 i$ W! b% \6 N- f! I8 F' u参数解释:
3 i- b; E* h" E; o" g0 \3 Fistrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流- b' y7 r, E( x9 ^2 `
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
+ j  I( N0 q( p* C, y2 O7 Q' y5 H  l3 n# B返回值:" L; k9 a* f: i6 Z
返回非0表示计算成功,0表示计算失败有错误2 k/ |. O% Y6 m0 C: {

, y; F6 P, @% ~& t' }8 Y + b+ Y2 b& q, B3 V% A

0 K6 T0 l. Z- }+ y程序代码: % R8 }* G, v* O1 z( Y, [
$ c" @! [: U  b9 M6 _& r3 ?
namespace fy_Exp{
& B. p+ E7 s8 g/ F/ T3 ~! Inamespace {template <class _T>  k7 L, [2 j( j2 F* H% G
inline _T GetExpValue(_T t[], char& csym){7 E- l! A2 a1 u0 Z6 V7 d4 c5 f7 f
    char c=csym; csym=0;
( x1 y( Y8 ^; q    switch(c){
2 e5 Z) B  T- f, I, q& U    case '+':return t[0] += t[1];
$ A- }7 D0 L, F7 Z! {    case '-':return t[0] -= t[1];
3 w$ d- L1 n- [. S6 m7 M- J% L    case '*':return t[0] *= t[1];
* s- c" g* b; P    default: return t[0] /= t[1];//case '/':2 g: C2 O% Z3 D( z3 V
    }
% u- a$ v2 |1 D6 N}}
5 k+ }2 P: Q  d8 p1 ], G$ r$ @template <class _T, class _Tstream>- z; A' g  C9 }3 K; b
/* _Tstream: inputstream, _T: get return value; J- x4 Z4 ~1 ?+ {# g8 l6 j. Q
* Return nonzero if get value successfully */
6 \9 `6 ~; C1 P2 bint GetExpValue(_Tstream& istrin, _T& nReturn){
" G3 m' o' Y- |" y! o. Q# e& A    _T t[3] = {0}; //雨中飞燕之作
3 U2 D% I$ l5 b  B3 H5 ~7 W    char csym[3] = "++";
2 l# V/ I  H9 }4 }+ _! q    int nLevel = 1, nERR = 0;
5 B1 G# u, |+ x3 O% B$ y    if(!(istrin>>t[1]))istrin.clear();! g' a# ]; P- p, _4 |. S! a
    for(;;){" y0 ?5 q- R6 n3 S" K
        if(istrin>>csym[2]){6 }* N% j+ _$ Z9 B. r' \! c4 ~
            switch(csym[2]){  X% t" s4 m4 A# B6 w- c
            case '(':, e4 z, O, h9 ?$ A
                if(!csym[1]){nLevel=0x100; nERR=1;}else3 ~5 h5 X1 N, _. U; }
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
: p7 v, C( |( V, k8 O: n5 l                else{nLevel=0x100; nERR=1;}
3 v/ M' }9 Y4 {  f                break;
8 K, p) B2 y: f0 z" `( X3 G            case ')':
" c) w$ F. w, u1 C# O6 ?  w                {nLevel = 0x100;}break;
3 s+ k& `* B2 G3 w            case '+':case '-':case '*':case '/':' _& P$ d8 B6 E7 P9 U- |& g
                {csym[nLevel++] = csym[2];}break;
! D+ C6 t, e6 H, D3 e7 M" Z0 `            case ' ':case '\r':case '\n':case '\t':continue;
3 E7 ?, d3 c. w! Z/ Z            default:
3 \. o3 j4 D/ H% ?- u                {nLevel=0x100; nERR=1;}0 e$ S! a$ V( O/ E1 k+ g
            }
) e7 s1 _- W; r. ]1 E: A            if(nLevel==0x100)break;
* y  S0 n) f1 F) G            if(nLevel&0x10 || istrin>>t[2]){! m0 B8 `+ U: R* k4 C& f" W, z
                nLevel &= 0xF;: m2 B/ E+ o) S" g
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}6 k* j% X$ a+ d7 X
                if(csym[1]=='*'||csym[1]=='/'){
& e. x+ H- s% c+ ]                    GetExpValue(t+1, csym[1]);
/ T5 d( C! A# d+ ^/ B                }4 P3 D. [- r, ?8 e8 S& S3 V: y
                else{
) J9 n7 ?3 H; w% E& ~3 V                    GetExpValue(t, csym[0]);
8 A$ l$ U' T' X" ~+ C9 j# o                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
) G$ b2 [% M0 B8 y- [/ n                }
; {* P. @. K; v! f                nLevel = 1;/ t! p4 C# B, B* z, e4 v/ q
            }
( o: r3 \4 w/ k4 M/ P% w            else istrin.clear();* [7 B3 k% X6 O4 @( s. h; c: W
        }8 U* i% w& b, p" G+ {
        else{nERR = -1; break;}
" u0 p/ ~7 D6 E! k3 G$ v    }) Y; s) a; G, Q8 M1 S: d8 o$ M; G
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
& @! z+ a0 W/ r6 G    else nReturn=GetExpValue(t, csym[0]);# K* `! }# _+ d0 k% ]: A
    return nERR==-1?1:0;  p$ X0 a1 H( Q( y: C% k3 {
}}1 t+ O" S+ y3 ]; `+ Z$ D+ j
  v" L3 K: O$ w
! U, O! A- R* d7 ?* P/ v
# F- t# e' H5 i" I: }5 S* P
函数模板使用示例:' Z) F3 v+ l9 n, s. B% h7 d2 g
在以上那段代码的后面加上以下代码:% S  r3 C! u4 f0 d- D. K+ J6 q
8 a. k# z; T; A, T: d$ R

) B- y7 f, h$ C3 a8 ]& D# n4 m8 a& Z% f5 x5 Q
程序代码:
* ~" U  {& U: _( v' i# ]) _
0 ]* a. y) p: }) Z/ G  J#include<strstream>
( y- k; N  ^; y7 A$ D! n#include<iostream># N% I9 c# D& M: j* R5 [* T3 @
#include<string>
6 e; l5 O! U& O* O; s& H5 Fusing namespace std;
; j* E5 i# |/ E7 ]$ M/ kint main(void)- H* d2 T( X9 O
{" {# f. ~/ Z9 l- B! f; [5 w
    string s1;
9 A4 k! T; g' q# Q    while(cin>>s1)
& K6 X, F% c0 m) y* U" s4 F0 x    {+ y, [0 h6 M7 g# f/ ]3 y3 o
        istrstream isin(s1.data());( a' J) F; f0 i3 X4 t
        double d;
& P% c& p* G6 F. `/ [4 f        if(fy_Exp::GetExpValue(isin, d))
: r4 I: |$ J% l( ~' G) [2 P) r        {
! l( u5 S) M0 u: I9 M; _/ Q" M            cout<<d<<endl;+ S3 T* N% S+ C, _& s1 g0 p- u
        }5 x0 I+ T% f# y
        else  {( J& L# \' a( L: y& c# u
        {
" t' }& h8 \+ B/ d            cout<<"ERROR"<<endl;5 t) I# H% \5 P- ]$ ]
        }
: S7 g$ z8 T( t5 O8 D    }
/ c: r; h+ E$ a7 }9 S    return 0;; }. c7 T6 [% @7 M% H
}
3 S) v; Z1 Y& m1 B
& q0 w: Y  l* ^, O4 v# g5 e/ C+ z0 x& ^4 j6 c. E. W0 ~$ B' q
然后编译执行就可以了(*^_^*)- K0 w7 s$ y* k, _. L( ?
其它:TC++上一定编译错误,不保证在VC6上也能通过编译8 L3 L3 f; J5 q, J
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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