Board logo

标题: 一个计算四则表达式的模板 [打印本页]

作者: zw2004    时间: 2008-1-21 20:17     标题: 一个计算四则表达式的模板

在9月8日那天我特意编写的,给大家分享的,* J/ F/ r" b" q- e/ s3 e
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
5 G) c% g  @6 ]只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)+ ^7 C( R0 Q4 v, j
参数解释:# F% D6 h- l2 E& W& @
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
/ o  t0 B* z4 \4 V# G/ @nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
. `) O/ D+ s0 n$ l) X返回值:
% m4 ?# p2 X, p% b6 r; k返回非0表示计算成功,0表示计算失败有错误" I% |: }1 o  ?8 w3 N7 M
9 m4 O% J# |( ~$ l7 X

0 l* s- {; o7 u. F( u- }. n: ]1 P
程序代码:
& m7 f$ |6 k5 v# N' O! Q1 l  x0 [
namespace fy_Exp{* B7 K& N" W  X( \# Y$ |* `+ Y# C
namespace {template <class _T>; O4 r3 l3 K2 {8 z
inline _T GetExpValue(_T t[], char& csym){
: a3 Q( H( y. ]% n- e    char c=csym; csym=0;1 O5 a2 a" M& N2 s1 O
    switch(c){1 E" O& i% X6 }0 Q9 s$ I6 A% u
    case '+':return t[0] += t[1];
9 }/ I) M  u2 Q! n( b( \4 C    case '-':return t[0] -= t[1];+ x( |) `; ^/ z( X- Q* z* d! s
    case '*':return t[0] *= t[1];/ ?; d9 H: P- }, B; m
    default: return t[0] /= t[1];//case '/':
* N3 L8 V  p; ]6 B    }
; D! y+ s' S3 e}}
  `  d$ ]5 S4 a' v+ etemplate <class _T, class _Tstream>
6 E4 e, s9 L) }; l6 {) \# d/* _Tstream: inputstream, _T: get return value3 G( h* x7 v3 d9 H
* Return nonzero if get value successfully */$ ^6 \: x) \- J1 \) n2 ^2 K( k% K# D
int GetExpValue(_Tstream& istrin, _T& nReturn){0 w; F) J+ B) \9 }& c
    _T t[3] = {0}; //雨中飞燕之作5 D1 H  D* H! G5 B! ?
    char csym[3] = "++";
% |5 C  a- I- f! G$ Y# ?! Z7 v    int nLevel = 1, nERR = 0;5 \$ C* X6 {" |; P& U! ]$ S: s1 Y
    if(!(istrin>>t[1]))istrin.clear();
' D2 B0 r2 i- s/ ~9 }! v7 P    for(;;){' D( m; Q4 C* |
        if(istrin>>csym[2]){) ^' B3 |1 r2 V. M# y9 y
            switch(csym[2]){
+ m1 r! V7 N; A5 s            case '(':6 w/ n. v& A, e3 r
                if(!csym[1]){nLevel=0x100; nERR=1;}else5 U6 o! W5 X7 B1 b& b% }4 C! j
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
- `4 F& J$ x$ E. i' y6 }: F4 y                else{nLevel=0x100; nERR=1;}8 k$ g6 o, u  t9 t: P4 e! Y
                break;# a: f/ S9 l# Q, }6 ^8 D: u4 ]
            case ')':; n- F( T3 {# Q1 P. x
                {nLevel = 0x100;}break;
7 {! W9 `) {2 l! Z            case '+':case '-':case '*':case '/':4 `0 ^0 ^; s/ j3 V- v) F+ Z0 N' l
                {csym[nLevel++] = csym[2];}break;, H5 z0 ]( d- d* j+ S5 W2 V! g
            case ' ':case '\r':case '\n':case '\t':continue;
# S' J+ d, Z# S# h+ r2 |            default:
6 |2 N+ V0 e5 b" t                {nLevel=0x100; nERR=1;}5 A# n8 U  P) X' `/ }
            }  ^0 G5 J& m9 ]2 _- S
            if(nLevel==0x100)break;+ J. P) m* m, U* J- m
            if(nLevel&0x10 || istrin>>t[2]){0 `5 `1 `7 m  w! C) i/ u0 {
                nLevel &= 0xF;" U" n  @% _% m0 i
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}$ T" |+ P% x# H4 O: W6 R1 J, J- }
                if(csym[1]=='*'||csym[1]=='/'){
5 b6 Y: J5 l1 s4 ^4 m0 S8 T                    GetExpValue(t+1, csym[1]);
/ g  }6 U/ w& S% `                }$ C- T' r* o& X$ [+ l. i; Y
                else{5 F" n9 O; v! b, p( M
                    GetExpValue(t, csym[0]);
  C  r1 e9 M) H" L5 I/ S; c                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;( u) E! j  }, M% ?+ z0 R( x
                }+ Q: C  P4 t/ O( C7 z: F0 w$ D
                nLevel = 1;
- }1 b. [2 D' \8 |) b2 e) |3 \            }
7 N# q, e& ^; }4 `( A, d6 v6 v# n            else istrin.clear();& G# n  a( R' M" J5 b8 X
        }
; f+ c0 D/ R" `3 d" i- t        else{nERR = -1; break;}
8 V1 f" c, c7 x4 s9 i    }
. M- z% i3 t+ `7 e  i; {$ `, F    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
' L! n- c$ I/ L5 W    else nReturn=GetExpValue(t, csym[0]);# g2 i0 A1 _4 v) P: n
    return nERR==-1?1:0;
. \8 ^5 v; D  o: u0 r, o}}. E* I# m8 G. D

7 ^5 W3 S. h: W+ |0 m5 b' Y
2 }' r0 s- ]: i( i# i4 `# V. i% R) r7 s' l2 C
函数模板使用示例:/ y) w6 T6 d8 M; F" w! f' g
在以上那段代码的后面加上以下代码:
' f7 E/ g* K) n8 s! ?1 {
. E2 |. Q# v5 f- p  C9 o5 \ / C6 S3 m/ ]5 l' r! o

2 e8 t: ~6 B# b! i( o! _程序代码: / s7 j5 h; t, k# T/ g8 l* ~

2 \% u% o, G+ {7 y7 k) a#include<strstream>
6 J8 ?. K# R+ S2 S9 o- j! d#include<iostream>
$ ^9 X# Y9 f5 V! `#include<string>
, v' f- J# D4 F7 y6 A# Kusing namespace std;: g7 F. j) q- i' w! @! g+ c
int main(void)) ~9 O5 ~- m! i5 ~' R5 ]  R0 f
{  o  b: M; a# g" c; j8 w) u
    string s1;4 c+ }. W' q' N! U4 w' U( L
    while(cin>>s1)
( S0 _, }# L% X3 Z+ F( q5 Q6 f% Q# n    {8 _7 S; y8 m0 E) p- `0 X# T& I
        istrstream isin(s1.data());
# z$ t4 |1 B+ U. Q8 K1 s# X        double d;
0 W* _( A) x8 _7 l" u% J$ c( w. |        if(fy_Exp::GetExpValue(isin, d))
" `0 L' `9 _8 b' f        {
7 a# r/ {4 K; z8 T/ t0 g$ x            cout<<d<<endl;( H; ?; B- F: {, Q7 i
        }3 q9 r4 P7 }5 R# ?2 K& ?
        else
; I% A2 [* ]+ `        {
4 e; I6 D' O3 O& I; c            cout<<"ERROR"<<endl;
4 {6 J7 S* P# a& v        }0 R' V2 L7 \' }
    }+ B# H3 U: k: g) x
    return 0;
: y, J" y) \0 ?2 t% J6 g; T, c, O}
& S- m* L: Q) Z9 s- b, N* Q5 y; m7 `% C! z  J

$ E- @, v/ b* z  O然后编译执行就可以了(*^_^*)! ^  B$ c1 C& j( f& f& `2 `
其它:TC++上一定编译错误,不保证在VC6上也能通过编译
" D2 g5 C3 x& V) [7 y! u9 s      建议使用VC7或VC更高版本,或者使用GNU C++编译




欢迎光临 捌玖网络工作室 (http://www.89w.org/) Powered by Discuz! 7.2