Board logo

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

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

在9月8日那天我特意编写的,给大家分享的,
4 h0 X: Y! n0 h一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
- [# H  G. _, x5 x" Z- t& B只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
/ i2 R2 W& k$ a6 j/ H4 Z- L. S+ v参数解释:- S8 L& a1 A* w
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
) x0 f' K+ Y& \2 q  L% k5 f* L9 `nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定+ ^- s5 g% @- m% Q5 u! F
返回值:
& u0 E1 s+ N4 p& O% p4 Y返回非0表示计算成功,0表示计算失败有错误; I3 l& H8 H5 p( K8 B9 X+ p1 }

" t0 `& m3 x: k, D# f1 p9 n4 _: [5 X3 N 8 r& `% E& b( @9 O& Y# ?
" c" s/ C( u' x; n* M
程序代码:
8 ~; I% q5 H0 _9 V1 P5 ?; r( c0 X/ k* r
namespace fy_Exp{
4 H' L* ^+ n: y& ?- S- o+ {namespace {template <class _T>
; o6 V( @; ]. Tinline _T GetExpValue(_T t[], char& csym){& c: q& A& \7 Q' D$ I9 n0 A- f+ D
    char c=csym; csym=0;8 V; o1 L. C  t5 X' c* u% F( V
    switch(c){
# I" m' ], ^0 g) K6 z( f    case '+':return t[0] += t[1];
  Z) U+ R0 i) H  b! P; P2 _    case '-':return t[0] -= t[1];! Y. y+ G/ r1 v# V% B7 ^1 g; H9 O" v
    case '*':return t[0] *= t[1];) j! Z) x. N, v  O! o. N8 t% ^
    default: return t[0] /= t[1];//case '/':0 N1 r  Y0 h1 p& q7 g* M$ l# p
    }
/ U" ~- K3 E9 y$ i4 e5 z}}+ b) {2 B' j. m) y! m; D
template <class _T, class _Tstream>
$ U4 k( B  c: l# b' M/* _Tstream: inputstream, _T: get return value& I4 Q3 T/ R1 z; ~  ~
* Return nonzero if get value successfully */3 }9 {7 ]. ?- X0 R
int GetExpValue(_Tstream& istrin, _T& nReturn){
) c1 m# Y3 s3 k7 _5 c    _T t[3] = {0}; //雨中飞燕之作
# A4 }* M% p0 _0 \" y! A" S    char csym[3] = "++";
+ E' A+ T3 V* }% J( g    int nLevel = 1, nERR = 0;) q6 t2 e3 i" p5 z; T* u
    if(!(istrin>>t[1]))istrin.clear();
" H6 s/ P* ], L3 V0 x: g    for(;;){5 _+ ]0 s0 E. s- }% @6 R- R: V
        if(istrin>>csym[2]){
/ X+ t  P- T5 Y& i" k5 Q! j- Y$ N& L2 y            switch(csym[2]){' w# N3 R4 f3 t2 A( I+ o
            case '(':( K* M  g5 ?  k  p5 Y( M, f2 A) `
                if(!csym[1]){nLevel=0x100; nERR=1;}else- i5 `7 h/ |/ M
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
9 w- ^- Z& H# Y1 l0 V0 L6 A                else{nLevel=0x100; nERR=1;}) y& Y6 G  [3 U
                break;
" a5 l4 F& S% z" Z2 B/ t) ^            case ')':2 S0 |+ W2 i5 `' y
                {nLevel = 0x100;}break;
) y8 V5 _  f, j& H            case '+':case '-':case '*':case '/':
; K- h# H0 t3 B, K' L1 @                {csym[nLevel++] = csym[2];}break;2 H; m! x3 E( r$ H/ W: L5 f. Z+ k
            case ' ':case '\r':case '\n':case '\t':continue;
3 y+ y: H* ^: C% {1 @0 w" c            default:0 W; u, }  X1 F6 Q" @
                {nLevel=0x100; nERR=1;}5 R% E  U& s  W  N% k# Y2 k% L
            }* K2 [8 r- r1 E5 s) `
            if(nLevel==0x100)break;
3 }6 k* C9 J8 F            if(nLevel&0x10 || istrin>>t[2]){* u3 G" i+ ^5 e
                nLevel &= 0xF;# |  E0 Q2 w& V' |' j2 P" ?
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}8 \. H' }% r7 U8 U" @) B9 ~
                if(csym[1]=='*'||csym[1]=='/'){
) N+ o* N$ E1 t$ _8 p                    GetExpValue(t+1, csym[1]);
# X) r0 ]+ Y/ E) j5 f* u1 p                }! F1 w! G  G& S+ ^8 e
                else{
) p  c; D" i1 c                    GetExpValue(t, csym[0]);$ D) R9 g& j1 p+ c# Q9 L6 n: Y
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;2 r1 Q! y7 ]( T+ g: A
                }! i6 Z# w( a5 |* i3 q& Z+ }
                nLevel = 1;% a" s; [$ Y$ t1 u' Q6 [& M
            }* R. E3 J. O6 N; I4 d3 d
            else istrin.clear();$ \8 ~/ L: g9 Y0 S0 e, p
        }
, a5 g6 D9 ?" i5 @+ V. n5 ^        else{nERR = -1; break;}
2 L; i; q1 W3 v8 W7 `, T% [6 A    }
) h# o9 u* h% N( b. N, }    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);) b1 j9 ^7 K4 h5 ?# y* x; z
    else nReturn=GetExpValue(t, csym[0]);. Y$ K  U0 k3 w0 L4 H% T
    return nERR==-1?1:0;- h' ^% G$ Y8 P; l
}}2 U( x: A3 O. b+ Y
' R6 K4 v9 g7 i  _

9 _. S  B3 t- C9 t9 a, d
5 h; Y% z( B8 b' w& L函数模板使用示例:
, k4 N. U. ^3 Q! d: l在以上那段代码的后面加上以下代码:1 a4 [& m9 O3 s4 G' t
( \, R- |& U' s" s  x
7 y) k8 |; z! Z7 p# z' o; Z" U

7 G' A' {# S7 D# R程序代码:
% K: Z- ]9 {5 _) g3 v6 a$ g, D! `4 q8 K" J% G( P+ v% G/ N
#include<strstream>8 }4 S1 O' b% h9 D, D
#include<iostream>
; Q, a( z' C0 O8 U8 o#include<string>
4 i4 @7 U( Z. r2 H8 h& Xusing namespace std;2 [. W. o; [1 W/ B5 `/ l
int main(void)
- z1 V# I8 B0 n! b2 _{
. {) \' I- w- f) x% A; N    string s1;
) s7 q, F9 {) I* `1 {5 ?. f/ Z    while(cin>>s1)
) F* ^2 G) F. K5 u; m) k    {
# g; p; a4 a0 G% j% w        istrstream isin(s1.data());. A6 b* j. A4 C3 b
        double d;7 n+ @# r2 s) S% _* A; [
        if(fy_Exp::GetExpValue(isin, d))& Z0 J# b. [( }3 b! s- K! E
        {
6 H- o3 X* ]; `+ i1 V, f! T            cout<<d<<endl;
$ n* C9 I+ f* C& p: A2 ]1 I" c        }
- ^7 I9 V5 p4 V. h        else
" m  p  E1 i7 ]4 ~* \& g        {
& @& {( E+ }* Q$ D, E            cout<<"ERROR"<<endl;' _3 b8 @. ?/ O9 X% e
        }
9 Z  L7 d, J# O/ X" E' @# o- C8 T    }
: Y2 w) |- F9 W$ m9 V4 @    return 0;" U$ \4 @) |5 Q: ?; v% c' V
}
! M9 W, @4 P% p2 V/ k! M3 l! I, r8 e$ u+ L7 W& |/ }- T
. [5 s" }) A/ e* @: s4 t* D4 `
然后编译执行就可以了(*^_^*), Z! l2 j0 O$ k# e/ U3 p
其它:TC++上一定编译错误,不保证在VC6上也能通过编译' x( ]$ V' D& k; b% Z7 P7 h8 C
      建议使用VC7或VC更高版本,或者使用GNU C++编译




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