返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
: k1 I5 v3 u/ D2 M3 i) N一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
4 p7 ], W9 x& B" G8 S" n2 ]" h只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)) b5 `% m, c2 _: O4 o
参数解释:0 v" ]/ U3 F% D' H, Z, @
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流; U8 U, @! x, \6 d6 r' ]5 r- T
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定1 K) |& h# B) c7 O7 G3 C. J- {# i
返回值:; ~" C) K0 D; T0 a1 l
返回非0表示计算成功,0表示计算失败有错误- ]+ W6 v% Z, f( P$ I5 S; `& p
- u9 [. L. N. R( p% x

9 X) {" |% x! {2 ?2 F% }2 i8 N* q4 c# O: t2 b
程序代码:
( k, t8 C' h- K/ j
1 O5 c* ]3 P( i9 V. H1 X+ tnamespace fy_Exp{, z2 Y/ N$ y2 n3 v6 T) e
namespace {template <class _T>* Y0 \* u" j3 q
inline _T GetExpValue(_T t[], char& csym){
* ?* N9 e4 Q! b( I/ T) y$ a    char c=csym; csym=0;0 W- d5 R) o! x/ @6 V# {7 [" p7 J
    switch(c){: c2 }0 S, K# F+ }, h3 i; P
    case '+':return t[0] += t[1];' w9 ^& H* R% W5 |5 r9 {( p; q6 L
    case '-':return t[0] -= t[1];+ Q* k! ], U6 Q( x6 Z# W* \
    case '*':return t[0] *= t[1];# V  r9 G( y& q! |
    default: return t[0] /= t[1];//case '/':
* _4 b+ v  H# R, @2 p    }
: P1 v! q' N1 p" q3 n( I8 K+ L# P}}
& m  l1 v& P1 q) S. d& Y- Y2 |, Ktemplate <class _T, class _Tstream>  ]2 E, c0 }2 Q  N( y- V
/* _Tstream: inputstream, _T: get return value9 R( n/ T9 T" |  G9 s
* Return nonzero if get value successfully */
7 V+ r8 f* [0 z9 q6 w8 q  y/ Xint GetExpValue(_Tstream& istrin, _T& nReturn){
# L& [7 i) r" ^    _T t[3] = {0}; //雨中飞燕之作
: U! k1 E$ q; ^; \# ]' i2 L7 s    char csym[3] = "++";
' B2 s* \, w8 k6 ]  p    int nLevel = 1, nERR = 0;
6 y! k2 t2 d' W( ]$ T    if(!(istrin>>t[1]))istrin.clear();2 `/ M, `, r! v  D. W+ i' {5 a. D
    for(;;){% x& G7 R# x% c& t3 M( ^0 \4 ~4 W1 w
        if(istrin>>csym[2]){. V/ z+ X  }+ [% s# ]( p
            switch(csym[2]){% z) e8 t. m6 s6 B
            case '(':% X* `% h" }" E0 O: m8 u0 |/ `
                if(!csym[1]){nLevel=0x100; nERR=1;}else
3 v/ ^# M- b1 M/ r9 Q7 a                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;- P2 C( n3 m  _0 d  L
                else{nLevel=0x100; nERR=1;}' w$ ?* i' L$ A3 k5 d
                break;" ^4 x# k4 @1 X0 w  n, v: m
            case ')':% J. w( j( @0 ]$ \  d
                {nLevel = 0x100;}break;
- R% G( z, r+ n1 u: |/ f            case '+':case '-':case '*':case '/':
0 s/ \0 i" U1 O  Z2 u& p; d$ J- ?1 }                {csym[nLevel++] = csym[2];}break;
" M: {1 r6 g; A# R( _7 l8 h6 b7 B            case ' ':case '\r':case '\n':case '\t':continue;: u* r! q  s9 D$ {( z& v# t
            default:/ ~& _# j; v5 w% z
                {nLevel=0x100; nERR=1;}
* {% y& V3 T. W9 E            }' \2 W* |# R$ ^1 u+ P& }
            if(nLevel==0x100)break;8 A- k# J% @, m
            if(nLevel&0x10 || istrin>>t[2]){" ^9 X. K' m2 E. }; ~/ v
                nLevel &= 0xF;
! w! i2 _- G7 e+ ?+ Q8 h8 }$ {                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}* C( ^+ D- w' F- {) h5 ^- l- }
                if(csym[1]=='*'||csym[1]=='/'){
. x! B/ L* K. s, Z                    GetExpValue(t+1, csym[1]);3 l  u5 u% J# d" [) _$ [
                }
# L, T% M: i: f( D5 h2 y                else{
3 y* e. ^* G# ]; s% h- _                    GetExpValue(t, csym[0]);
* P/ O# K# J$ f0 e+ @) j7 x% |5 F                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;# A" C9 m+ x! |- t; f
                }
, t/ [6 ]0 n* v% A, T                nLevel = 1;
' g" P5 v9 Y( u+ `            }
" S$ S. Z; C. O( M            else istrin.clear();! A/ B! w7 y6 T) n; c$ |% U
        }" t% J2 N. `8 f4 c
        else{nERR = -1; break;}
0 [0 ^, K7 W9 N/ o6 t    }* o' |' p8 B) K/ l  F) a) N
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
# e1 H1 h$ D, G3 V    else nReturn=GetExpValue(t, csym[0]);
0 _( C' H7 ~# i9 }    return nERR==-1?1:0;
  O# b" Q: y- r' y2 `! `}}  }/ Z( H( c1 _' D, i3 r
+ l# o. P* D3 y
  G- T4 Y- Z6 }6 M

" R( J8 I5 K# h  g9 J  ?- \函数模板使用示例:3 N$ T5 y+ j+ z# g
在以上那段代码的后面加上以下代码:# @7 P0 z! l. g, L% P3 C
' o# k. r- y6 R# ^3 b

- g! ^/ l# f$ |, O8 s: c4 O2 G- p, [& `; f
程序代码: % H. ~9 H* e) }9 O5 l. t- ^
7 Q! F/ q) Z. C( p: c3 O
#include<strstream>' j$ g! @3 |5 A% U& X
#include<iostream>
" K& Q6 A8 J5 R! T#include<string>! W8 o4 q: X" n5 i/ `( W, c3 N
using namespace std;! w+ u3 `0 e% w6 M
int main(void)
$ V$ q, ~0 G& |( r* k{
* @" i6 R0 Z* R    string s1;4 Y; i2 l1 e2 V. V
    while(cin>>s1)
- T! N7 z( k# H7 C! J  K! {    {
3 J  C9 n& c2 b. w. z& `! a        istrstream isin(s1.data());4 I) E. t/ [) d/ Q, Y8 q
        double d;0 [+ G0 m7 w- I3 w3 \8 m
        if(fy_Exp::GetExpValue(isin, d))
& ]/ P" X8 ?2 L6 o* v: O: L$ A2 Q        {
% `, h+ s# K* C# Y6 G% l            cout<<d<<endl;
* x3 r2 {" n4 f        }
/ N6 r7 H$ f( B        else
* d5 Q) q9 \* ]6 Z* i        {7 T* X  v$ D% X& n9 r; Z8 [" d
            cout<<"ERROR"<<endl;
0 I! x6 I. T  |4 k        }
% p' ~$ i  h+ }3 K# P    }
# n9 y/ }: m/ @7 P    return 0;+ I% p. }: o3 O" B( \8 ^
}) T- Z1 y  j* o# d! B; l. a( P* H

$ D; p4 `9 W5 x9 K  v* X4 r; Z1 n- ~9 y* `2 x1 R( q, L! j* z
然后编译执行就可以了(*^_^*)+ O  [7 Y& t3 R! }  ~4 k
其它:TC++上一定编译错误,不保证在VC6上也能通过编译
5 g6 t; K2 I- K& G      建议使用VC7或VC更高版本,或者使用GNU C++编译

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