返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,) Q1 {9 f+ F( d: O
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式4 r$ f6 |' f" K
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
- t9 t/ O8 ^  S. t参数解释:: N. ]$ _) A2 f
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
3 s' p: t, x9 g0 F$ ~nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定* S1 B. \* }; \+ a/ G
返回值:
( `8 F/ h* v+ z5 `3 X返回非0表示计算成功,0表示计算失败有错误  t" r- X4 c5 M+ ~$ i

8 ]+ z; p" V  @- o; p% V) p : K# t& ~7 o& L9 N

: n5 [$ r3 E0 M$ w" Y程序代码: * C; ?0 L3 P' i5 m6 E3 U8 g

" c( n+ u& T6 r" i0 ynamespace fy_Exp{; I% G" Z4 y- \) h. E
namespace {template <class _T>
* R$ J" ?6 J% g6 uinline _T GetExpValue(_T t[], char& csym){8 }8 G, L; R) t4 [0 n
    char c=csym; csym=0;- O. [* J/ b% i9 E) {6 n) \  C
    switch(c){  Y+ g3 E. y: f, }
    case '+':return t[0] += t[1];
/ F7 _  t8 K& H+ O1 ]    case '-':return t[0] -= t[1];
( K6 |) i* ^1 J* B/ _6 R- K9 s7 u8 |    case '*':return t[0] *= t[1];6 m7 `4 [  H/ C+ I! ]" K
    default: return t[0] /= t[1];//case '/':4 q* i" v! \, |
    }4 X+ \, L& |, U7 B( N' n
}}
5 ~- D+ D, Q; O1 Ftemplate <class _T, class _Tstream>
6 l/ n% r4 n& F1 Y; w* a/ ?/* _Tstream: inputstream, _T: get return value/ z. r3 ]5 E) E/ s0 ?/ I" L1 u  s( p
* Return nonzero if get value successfully */
( r$ x  c0 V# A3 Z+ ~" f, tint GetExpValue(_Tstream& istrin, _T& nReturn){
: d- f7 m& c- O3 v: T    _T t[3] = {0}; //雨中飞燕之作
; E: [( Z+ L- \  b    char csym[3] = "++";
; y; a9 H' M9 p4 t( I, C/ U; d    int nLevel = 1, nERR = 0;
  N+ `3 i3 l8 \: n    if(!(istrin>>t[1]))istrin.clear();
9 Y/ u8 P  ?6 X5 C+ _/ h2 N6 c    for(;;){, S! Y+ Z- \# B: O$ A$ J
        if(istrin>>csym[2]){: W$ W& I% ]# i4 C% }+ ?  y: }6 o
            switch(csym[2]){
9 P  o6 H: [+ O# ~, j( e            case '(':1 d; \* @; I; O1 L
                if(!csym[1]){nLevel=0x100; nERR=1;}else
7 R: ]$ K6 O9 k9 |6 J- t  h2 }# W                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;2 y% B$ @1 n* @3 ~7 w5 t9 B4 j
                else{nLevel=0x100; nERR=1;}& v6 J8 w6 K1 \
                break;
4 d9 c) y+ u. D! ^% A8 A% R2 U            case ')':
& A6 B$ X/ S# s1 o5 v                {nLevel = 0x100;}break;1 c( A- V) Z! c5 a/ H3 ?
            case '+':case '-':case '*':case '/':! t2 @/ N& |* ]- F1 F# m5 {3 ^
                {csym[nLevel++] = csym[2];}break;8 G" {/ i$ X; x% b3 o1 y" Y
            case ' ':case '\r':case '\n':case '\t':continue;
* ]4 Y$ K6 A( f) _" Y5 M, y            default:3 t) ~& C4 m( T# _+ w
                {nLevel=0x100; nERR=1;}
9 t, H$ e  c4 l8 {+ Y+ b4 }            }: O4 w* X! _! R* f& I
            if(nLevel==0x100)break;" n% e( @; h6 O; z5 G  b4 V
            if(nLevel&0x10 || istrin>>t[2]){
0 m7 V  U, [0 {' F& s                nLevel &= 0xF;: y7 b. r/ F$ i, p: I" s6 H; }
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
* d! e6 ], C! h9 @" H! o6 H) A                if(csym[1]=='*'||csym[1]=='/'){
$ D# s" b7 W9 f! A& t- e% h& T1 O                    GetExpValue(t+1, csym[1]);
2 d5 ?3 D  j8 p4 y, z                }
. v% v: ]3 D3 g8 K5 g! F                else{' j, k1 B( }8 b- f: p$ v
                    GetExpValue(t, csym[0]);+ j; U5 j* O9 E+ R7 [. N
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;# S/ {1 G+ h6 ]1 L; \
                }0 a& l: T( W5 f. }% X
                nLevel = 1;3 T  ]& C/ B4 g! I8 f8 ^' a
            }
, P- V5 g* |3 D0 A( F  o            else istrin.clear();
" ]) T/ [9 p. Y        }% s9 I' ^& P. h; k% z
        else{nERR = -1; break;}
/ j& m# |$ S6 u6 a2 v    }  y6 {5 [: K/ M3 \9 V+ r7 T9 K* p
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);7 S& W; p! n# b/ t4 I& q; n+ f! w
    else nReturn=GetExpValue(t, csym[0]);  ?' W& K8 X4 h% N% C$ e, K
    return nERR==-1?1:0;
- I: E; n# k: g4 u% A, N; E* @}}
# W! y2 I8 f! W3 T( u  h5 U* P9 u5 Z! m0 \0 g
! }' M/ o) C( ?# x) M2 o) Q

! }( A6 z  S6 X1 U% V: v函数模板使用示例:
# z  X9 q4 B& Q, s' l2 s在以上那段代码的后面加上以下代码:
$ x. c2 i; d% c7 J4 f! @8 ~5 M/ `8 h8 d# i) d4 _% F: A1 p3 U
' d4 P: F. X- P8 z* C0 W) j

2 n' K- M$ Z1 r' m5 o/ Q! _' z: S程序代码:
& I: z. q6 U; c9 x8 P/ K  J% m5 W3 e$ ~' X
#include<strstream>
! F$ k9 n1 @. @6 w6 Z( N4 g#include<iostream>
1 r! e6 R0 r+ X& ~: C#include<string>) T4 r1 q) T+ R# c/ \
using namespace std;
: z/ e# L6 R2 p" j( V5 d8 n: B+ E8 a3 ~int main(void)
3 s9 h1 c. J' Y1 {7 P- g7 G{
  u1 Z/ |; V0 T  \# C    string s1;
) E9 R5 A  P# y    while(cin>>s1)8 j. D/ t+ C' L0 L- H
    {& ^0 M( m# G- m$ [
        istrstream isin(s1.data());
2 y7 S9 d2 p/ l4 n# ]4 S% L        double d;
  K( `) o* K1 U: F! i2 b% e        if(fy_Exp::GetExpValue(isin, d))
5 \$ g8 t7 _- n8 o: R2 o& ]1 n( `        {
1 J6 n4 S4 b0 M# k! G' G" J! p            cout<<d<<endl;# w6 ~! @  U4 C( H2 F4 y
        }. v# U9 J# i8 y" a5 P6 d
        else
# T1 V) n/ L3 k        {; c( n+ ^; T1 s
            cout<<"ERROR"<<endl;
* O1 r. x" q6 m: N. S0 q        }
# m- U% i) V2 H1 w/ U7 U# L9 J2 T    }
) S/ R6 Y: S* @$ Y. c) W* x( j$ ^    return 0;0 }; B/ `7 |! D% y6 p
}
  F* H+ V- w( o1 L
0 c+ T7 u2 y' F7 R0 e: G( Y2 X1 ]9 p; C  z- Q) S8 s. S
然后编译执行就可以了(*^_^*)
& y1 j  W0 ^1 m, j5 B/ h* f其它:TC++上一定编译错误,不保证在VC6上也能通过编译4 |2 x7 i+ f2 ]; T
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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