返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
0 d+ k3 V6 k+ `4 c& }# `1 \0 o& `一个很方便的函数模板,可以并且只可以计算含括号的四则表达式* Z1 i4 V% X; G( L3 b
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)8 p8 {  z6 t7 P9 c) J" c1 d; O& L
参数解释:
1 G$ |& @  O% v/ d( R& {4 Uistrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流4 }6 W0 N& [# K" N* \, I! E3 F
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
+ y3 @/ x. r9 l3 b/ F5 x1 P返回值:" ?, [; J4 v1 d/ u* _8 B
返回非0表示计算成功,0表示计算失败有错误  x$ p  {8 L4 B6 |  ]* d1 x

, H- F/ A! \$ ^) B( Z) ? ( T7 g# ?# N/ Y9 [% V+ \9 X9 J1 j

. g/ n2 v- }# j; a2 m3 A. J程序代码: / E# i7 v+ x' Z
: N' ^- P+ d; Q# M& g
namespace fy_Exp{
$ j+ R" {6 p5 a4 C( Pnamespace {template <class _T>( ~0 h$ _: h; g' E% l0 J1 u, i
inline _T GetExpValue(_T t[], char& csym){
  x) ^, i& d7 B/ Y) S    char c=csym; csym=0;9 ?# N8 O& V" B+ A5 N. U$ m) {, o
    switch(c){2 q& ]  w: h( W  V( F% i
    case '+':return t[0] += t[1];- J. B4 \9 V6 ?% b
    case '-':return t[0] -= t[1];% R; T* Q: \: P$ O( l1 F/ B
    case '*':return t[0] *= t[1];
3 h% q% \+ o7 ]. ~+ [    default: return t[0] /= t[1];//case '/':% ^) E8 S; G: I! }" C
    }& ?5 T& R: h8 h4 h7 F0 c
}}
: f8 r- y. T" H$ ]) qtemplate <class _T, class _Tstream>2 l) q; ]* d( S9 J1 ]
/* _Tstream: inputstream, _T: get return value
3 N3 J; {2 W. z; z# Z3 H* Return nonzero if get value successfully */
) U; D" `! U0 X2 M! v7 q6 Xint GetExpValue(_Tstream& istrin, _T& nReturn){+ `# F6 f9 ^6 B4 {+ P5 i
    _T t[3] = {0}; //雨中飞燕之作
( v: K% j6 t+ F) _  @& u$ m: S    char csym[3] = "++";, s0 l# j' y# d2 j/ i
    int nLevel = 1, nERR = 0;3 J( ^3 s% d# O7 B- M) o! Q
    if(!(istrin>>t[1]))istrin.clear();5 P+ N6 h7 o9 c% i
    for(;;){/ W% N0 N' J+ K
        if(istrin>>csym[2]){6 ^* J' d! T$ V# r
            switch(csym[2]){
( U, g& ]2 h0 M  H( a            case '(':
7 u: ?/ k9 a- _+ Q" ?, q' X1 w                if(!csym[1]){nLevel=0x100; nERR=1;}else
8 w0 l" h/ ?! k: z* v8 ~! r4 v                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
5 E( _2 D) ]- S/ d                else{nLevel=0x100; nERR=1;}
. Q4 k  n- q+ N                break;4 v7 I- T$ Z- F5 O) z5 U
            case ')':) `1 U+ |( u5 O( }; ^
                {nLevel = 0x100;}break;! M& a% s- i' `& H* c  Q/ x, D: K  a# l
            case '+':case '-':case '*':case '/':2 P3 R; y5 J. Q9 Z  p% h" p
                {csym[nLevel++] = csym[2];}break;
5 A8 P7 M& }- X7 N) a            case ' ':case '\r':case '\n':case '\t':continue;, T) \6 P5 b2 X' p
            default:- Z) I( _3 ?0 c$ y
                {nLevel=0x100; nERR=1;}. n! I6 P" @, f
            }
0 p. r, A; w- y9 s1 k' N            if(nLevel==0x100)break;4 x* j) i' {! f7 x1 `3 S$ ]& |
            if(nLevel&0x10 || istrin>>t[2]){
& d) K. m5 b$ @0 T6 S                nLevel &= 0xF;
6 P- j9 [) A. t, j' D8 z                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
/ \8 u% c3 M' r                if(csym[1]=='*'||csym[1]=='/'){
& e8 R/ j8 Y+ a' d# i; ?                    GetExpValue(t+1, csym[1]);
& X0 _& S0 r1 S2 m" Y% Z                }
0 c/ u) t8 c! ]6 w4 B                else{, k3 P! a9 e, q' e7 I7 h+ m
                    GetExpValue(t, csym[0]);
1 W2 u' B) y. s" J" M: T                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
3 M6 f& I' U' e) C                }
2 V  m7 v" D( [" Y+ E4 P1 |0 s                nLevel = 1;8 P" `# K0 y$ ^# N0 K
            }) ~  V$ o/ E0 A/ g0 r
            else istrin.clear();
& g" }6 L9 S& c        }; u5 B5 v; T, D, ^3 N
        else{nERR = -1; break;}
$ D2 C3 A  e2 N  Y3 e6 o; M/ M    }
: G8 P7 I9 z0 T2 M7 Y" Y: ~, U    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
6 I; i! \% Z  x" u- k    else nReturn=GetExpValue(t, csym[0]);
5 F2 a- D5 v8 ]* g& g" A6 U    return nERR==-1?1:0;
) \* |& D1 h' p* H3 L% h9 t}}* o8 ~' m6 i5 J* I4 h& y

6 T2 N& k" Q1 Q+ H) _4 ?6 I/ l: U0 @) x% i
) a4 O- R' M7 w4 ?8 ?* [
函数模板使用示例:
! e  h+ ?$ G5 P在以上那段代码的后面加上以下代码:
% ]7 U( D4 o& C5 U) W; P  F# M; b  l6 @* b9 N% f/ k

: b! x$ M8 Q( e& u) X
3 W' a* r: o' Q9 j2 P0 Y7 x程序代码: " I& ^' b& ]* F' [# @* @( P

1 \( n' a' `: f1 y  d  m# U#include<strstream>
5 o; x1 J+ u0 H& q/ c) |+ ^#include<iostream>
4 e% y1 g* C' Y1 c+ [#include<string>
, S( R: B/ s. p0 j0 F5 I: ausing namespace std;
$ `7 J! t; s6 k$ O% a2 Qint main(void)
" S; _% `: S, Z; ?; h{
- L3 W6 h& B% V6 G% D+ A& r( J    string s1;
) w$ I7 t8 M- d; v    while(cin>>s1)
) F* G5 n2 {( ?; l5 Y    {6 V/ o7 B" E7 W/ c, |8 p$ P8 U: ~
        istrstream isin(s1.data());/ V' [- I, ]9 t* a0 l$ c
        double d;2 m3 R, t, t! U) |( r
        if(fy_Exp::GetExpValue(isin, d))
/ I4 @* F5 I0 b5 z* y        {
0 y( X# h( h1 \( j            cout<<d<<endl;* r+ z0 N8 V+ K4 H1 z
        }  e5 q8 a) g3 B* e5 G/ V5 ^/ @, x. |
        else
- m' V! a+ J5 n! K8 _) S        {; }. M; a; P  R
            cout<<"ERROR"<<endl;
8 B' i$ P( }3 L! O        }. ]2 S4 J! d( x* `2 w$ y, M
    }' Y! ^; ?7 \1 \/ r+ L0 Z7 a
    return 0;, a$ P) |$ `' v- }1 w
}
- l, d: e" O; w0 v. l
  O, C) t; ]& y  v. A
& U3 f4 h% P1 v* W* e然后编译执行就可以了(*^_^*)/ e6 u  V* H- q- E
其它:TC++上一定编译错误,不保证在VC6上也能通过编译  \9 H( _  G( x7 t1 j+ |
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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