返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
3 [1 i1 \. \. J- p一个很方便的函数模板,可以并且只可以计算含括号的四则表达式) u. B- M0 |5 {
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
, O1 h3 z) T" j# i4 v# M* X参数解释:3 `/ F, M3 Y, A. m- l, p
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
  u6 A' e; s7 |9 V& t4 g- TnReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
/ n; d; G2 n0 h% E/ }3 F返回值:
$ L# z, W0 W" a  J1 _返回非0表示计算成功,0表示计算失败有错误7 O; J+ B! N! O+ n  p6 v$ T4 l$ Z
* ^+ s: \$ D  e$ E, ?
7 M* }3 {. l* }/ O" `

# @5 \9 D2 `; C程序代码:
: c  p* _! U6 m+ ^$ c! e
. I2 P* |2 U" T& Gnamespace fy_Exp{
$ p  [1 o& @( y% W; D, N( R9 Lnamespace {template <class _T># m, ~9 W1 b% f% H
inline _T GetExpValue(_T t[], char& csym){
: T9 q) o1 _) H' y* o% s& {    char c=csym; csym=0;( L) b2 w: m  C* U- Y
    switch(c){: y7 L- }$ i) p1 Y
    case '+':return t[0] += t[1];+ E$ g3 ?4 K6 T: m% ^: G+ ^- v! c8 B4 c
    case '-':return t[0] -= t[1];
( @- L4 _0 l! F1 B  O7 f# ?+ X% B    case '*':return t[0] *= t[1];
1 ^# `6 B% @% `  I    default: return t[0] /= t[1];//case '/':
+ `& I( y% y/ s  n, S4 s, G3 a    }
0 |7 n8 x; l* W}}' |, m% C1 ]( @) \/ `' _! N
template <class _T, class _Tstream>+ ?; M0 N$ k$ Y. u8 r: T
/* _Tstream: inputstream, _T: get return value/ Y8 Q  ^% x' i7 d" U7 |" {
* Return nonzero if get value successfully */& P2 U/ ^( d3 v2 F
int GetExpValue(_Tstream& istrin, _T& nReturn){1 d- Z1 C: B, T( Z: c3 n2 o
    _T t[3] = {0}; //雨中飞燕之作
4 e5 z9 I9 ^- ]( f! x6 d    char csym[3] = "++";
3 F3 E4 l7 `. V9 @! r6 x1 @! q    int nLevel = 1, nERR = 0;  F! F4 H' Q- H; @# U
    if(!(istrin>>t[1]))istrin.clear();
% a; c- i6 @2 _% t+ c) a, d7 U7 l    for(;;){1 O; p  n+ e- ~8 Z" q6 D
        if(istrin>>csym[2]){
5 p9 E; i, }7 K' j4 Z0 |            switch(csym[2]){$ v9 r# `" l3 F; |4 k, X/ C
            case '(':
# ~4 P% @; s* _1 x                if(!csym[1]){nLevel=0x100; nERR=1;}else9 A- k' z; M0 ?
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
0 E& z+ v; o: Z1 C2 N                else{nLevel=0x100; nERR=1;}5 `$ b7 O# q3 l6 M6 v9 I3 n
                break;
$ O8 o$ P' _# J8 ]            case ')':7 Y1 `* o4 ^; l/ C
                {nLevel = 0x100;}break;; b/ f; ^' b7 `) ?( g( s7 Y8 O
            case '+':case '-':case '*':case '/':2 ~' ~' |( Y; N2 h( a5 M" r7 f
                {csym[nLevel++] = csym[2];}break;) Y, p  ]$ f/ M2 @9 ?
            case ' ':case '\r':case '\n':case '\t':continue;
) {$ Z* x. \( U; B! B: i            default:
+ ~, F3 r' W6 ]* y                {nLevel=0x100; nERR=1;}% ~$ S" G/ ?# t- `: F
            }, t$ y8 h, a$ h0 o; ^- w( C. F9 _. W
            if(nLevel==0x100)break;
9 c* n/ u1 Z& C2 X8 I9 a6 c3 G- ?            if(nLevel&0x10 || istrin>>t[2]){# ~, `3 a4 h+ v! d
                nLevel &= 0xF;9 q( h5 z) y3 \# [8 H. L; {
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}, A: b. ~1 k0 u2 p2 ]2 ~7 \2 b5 j
                if(csym[1]=='*'||csym[1]=='/'){8 L0 |& d) _( b3 g, v
                    GetExpValue(t+1, csym[1]);* Q' {) [# s& ~" |/ P# o
                }) F7 D7 {: k* x, ?9 v; g2 R
                else{, X, F! R! ~) [& S" Z% P3 X
                    GetExpValue(t, csym[0]);
& O2 u' [3 f8 g# X( A4 o' F                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
7 x3 J. p/ \; |1 @                }" }+ m5 }: g+ i- D3 ^; }. Q7 n
                nLevel = 1;- ]4 n  F6 K- D" h* N0 Z! h
            }
4 a) ]" j2 C/ d1 ^8 ?            else istrin.clear();
/ h! u+ j3 n: z! T! F, S/ m' N        }
9 \" Q6 x8 ]! I( M/ a* M0 ^        else{nERR = -1; break;}. M- W6 d& h( Z! f9 a
    }$ Y+ f- E" e0 v0 Z) ~; q# n
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);; A5 @- I  D- X# F" @
    else nReturn=GetExpValue(t, csym[0]);
" [6 }6 S; q% V! r    return nERR==-1?1:0;
. b, L. I4 d0 G& R  U3 B! U, z8 u}}
) i5 p& [# H. Q" f1 {! I5 Z' V: @
3 B5 N1 ^! t! W6 A8 D5 l) f4 s
9 m' I2 L% H3 ?
0 D# x1 C2 \2 g/ l. b5 X函数模板使用示例:
" }/ _3 O5 F+ X- |  P8 {2 Q8 ~在以上那段代码的后面加上以下代码:
6 o0 Z* u& j8 P: ^5 g3 ~" o  h
, q9 A) C: N5 z6 f* b0 e) i
( N% L2 T. S. l6 _! ^4 r
/ ]/ O$ K* }" b0 m程序代码: - h' y, p) `: y- h3 R. w

8 W" ~7 ~- Y3 g9 {1 ]9 f/ \#include<strstream>
, B6 ~/ j+ f# v' p0 ], X, y' q#include<iostream>* }0 @8 e3 _5 v8 z
#include<string>
1 Y8 O8 w4 W2 t1 A2 a: r7 wusing namespace std;
- h2 l$ e( S# X# `* yint main(void)/ ^5 k/ m& g6 j9 [( C6 }
{( h: f! j% [- _% w; u5 B
    string s1;% f" ^5 E5 o2 H! c: r* E- T
    while(cin>>s1): k9 Y7 K2 j# N3 }& w0 Z
    {
9 q0 q) g3 {4 n$ N5 w$ I! {        istrstream isin(s1.data());- P( F) S5 ?. Y4 Q
        double d;
1 ?6 A! X- j( v9 T3 u& n7 \        if(fy_Exp::GetExpValue(isin, d))
5 Y& x- O; ^: d, \2 w        {
8 b7 ]$ c  H( Y* m            cout<<d<<endl;1 s: `- D1 O$ v' p% |$ ~4 K
        }
3 z& G* i, E4 I& F* f$ \1 U        else; o' D- X* T) c1 W
        {2 P( r* A& S5 a) j9 \9 D
            cout<<"ERROR"<<endl;
) i3 _, `9 u9 n9 z+ V1 u( l        }, A/ Q* G$ d" Q
    }" V/ U, k3 \+ S% K6 _: Z
    return 0;4 v0 d; D/ n$ q
}' r$ C9 u$ Y( m  U0 T* N

) b* V2 w- H2 J, g& ~' |! ~6 ~% Z& ]6 t% _/ }  A: e) l/ `
然后编译执行就可以了(*^_^*)
3 r6 y2 m. g" S+ x其它:TC++上一定编译错误,不保证在VC6上也能通过编译
- g& s% m- ?. j; V. f" X' j      建议使用VC7或VC更高版本,或者使用GNU C++编译

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