返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
  W& n# X# a& q9 M一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
& C: N( F0 U1 ^( d& e只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn), P0 ~$ w# {0 j% v' ^
参数解释:
' [* i% z- S( t8 L3 H$ S4 u& _istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
5 d2 X& p9 |( U6 _/ xnReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定; w7 M1 \9 y0 a9 x1 a
返回值:0 S9 [3 b# D, @/ `; h
返回非0表示计算成功,0表示计算失败有错误' A1 @# N) d& T7 ~. B! e' `; x- l
# x8 S! K/ ^! T; h) K9 E

+ p4 c3 @# `, V9 D2 _
4 P2 U& Y2 @3 G# n程序代码:
' _, }3 B# F# a0 t" P% g5 p- I; g$ ]" t: ~) L- K6 [1 G
namespace fy_Exp{% }& h/ Q5 e/ ~( u( c, F
namespace {template <class _T>
4 l2 _6 M9 S6 P; b4 ^" Tinline _T GetExpValue(_T t[], char& csym){( _9 }! s9 h6 m- [
    char c=csym; csym=0;
# [5 \: G$ G$ L) X6 B5 }3 y    switch(c){5 z6 [( `* m# i' U
    case '+':return t[0] += t[1];+ n% L! t% b# E5 i$ C; {
    case '-':return t[0] -= t[1];6 b# `; g# A8 m4 F) O
    case '*':return t[0] *= t[1];
* u# h+ E; k- Q( d    default: return t[0] /= t[1];//case '/':
$ _" v% r' I) d  E6 w& _5 \2 T2 r    }
. c3 T" y% k# x" ~' A. c}}$ y; t0 L6 P  ]( B( L" J. S; J
template <class _T, class _Tstream>
4 l1 u! f0 U( g6 l/* _Tstream: inputstream, _T: get return value
# x! ~3 t1 [# U; ~* Return nonzero if get value successfully */
9 y1 i. p& D+ q6 f/ e( _9 o) l. ~int GetExpValue(_Tstream& istrin, _T& nReturn){% Z3 e3 @; y9 f4 S" V+ \# \) P: f
    _T t[3] = {0}; //雨中飞燕之作8 x( R1 e% Q2 ~# h4 G6 |
    char csym[3] = "++";
# F3 n$ F; L0 _    int nLevel = 1, nERR = 0;
1 s; W6 L" \  ^- _/ s+ u* X# J    if(!(istrin>>t[1]))istrin.clear();
& C6 X7 _" u# ?9 x    for(;;){% n5 Z# R# ?. f3 n* d
        if(istrin>>csym[2]){
# F4 T& h7 R8 @' K# U9 X; m5 g6 S            switch(csym[2]){
+ w# q( P, j  d, O9 Y            case '(':' u1 h7 G/ D0 ?' n
                if(!csym[1]){nLevel=0x100; nERR=1;}else; U# B# _) D- E
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
" `5 k8 D3 g. p1 r' {/ `                else{nLevel=0x100; nERR=1;}6 m- r$ m- p. ]( }+ a/ _* A
                break;
* e; I* K! ^; b: F. k  j            case ')':
$ H- {# N) R/ _                {nLevel = 0x100;}break;2 p' Z3 f8 Y  c6 c# a
            case '+':case '-':case '*':case '/':3 W; M* B5 m- c% u4 `/ [/ J
                {csym[nLevel++] = csym[2];}break;
( _2 \# x- q( V& K            case ' ':case '\r':case '\n':case '\t':continue;: o. X6 J% E# W% }8 w- k7 }9 ~/ Y
            default:# k/ n) I- F1 `( C9 y
                {nLevel=0x100; nERR=1;}
) |$ h/ L, o/ E9 c            }) K/ ~% v/ Y# K" |1 F/ K
            if(nLevel==0x100)break;) e. \, o+ G, E- c7 m/ Y
            if(nLevel&0x10 || istrin>>t[2]){
/ k2 Q1 C& N) `- {' i1 z2 w0 d                nLevel &= 0xF;
. ]. R0 G9 o4 C7 s2 ]9 p( E5 V9 D2 |* m                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
+ |) w# j0 s9 t2 A- ~                if(csym[1]=='*'||csym[1]=='/'){
% ?( Z( Q0 O; a0 s7 C' G+ f                    GetExpValue(t+1, csym[1]);: e. A, X9 W$ Z- `% S
                }
$ F; I# t3 p4 m/ t/ x- O: M7 g                else{" o. q0 `6 G/ j
                    GetExpValue(t, csym[0]);! H9 _. h7 }/ U2 i
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
/ T) S; k8 l7 z& c, O/ w  S                }
' k$ ?$ P' c! H$ ~4 c                nLevel = 1;. s# c2 j7 N, m" P* x$ J% p) X
            }
- p3 m- k" _; G/ {* w            else istrin.clear();3 w7 L2 E5 j, ~0 X8 o( U" i+ e! n; `
        }' E2 ]0 E2 ]9 t7 [
        else{nERR = -1; break;}2 A5 _. F% c6 p
    }
) e  }: B1 c$ s& f    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
* m' L, q& x- v9 C9 R$ |    else nReturn=GetExpValue(t, csym[0]);% `6 j1 u: R) h% M6 E
    return nERR==-1?1:0;
2 B2 D6 b+ n8 [+ {}}
7 z3 J0 f% B3 {" g- ^# k# d
$ l" ]  U# \* ]5 G& b. Q9 u
3 r- T' G8 J+ W3 [0 g3 N( T0 I2 J0 r% h$ V+ l1 L
函数模板使用示例:# j2 C/ g1 v9 i; t
在以上那段代码的后面加上以下代码:
& _4 H1 m0 {- R9 q- q8 D
) K8 D0 R8 ?' i1 x , A+ i. N# f+ N% b( V

5 F  i( u' Q1 I: c0 a2 h6 R4 d程序代码:
% l8 y  D+ @" R  x' j+ {  d/ J
& b7 r! T. K0 I#include<strstream>
0 \/ X% L# `3 F8 M' a; c5 q2 H#include<iostream>) S5 a' K2 [6 o% f* o
#include<string>
# d; \8 N7 l2 i) Gusing namespace std;
/ c# |& ]! {3 p7 ~: q) _: Xint main(void)
6 u4 g9 I0 Q! z{
7 y! k) Q2 x% {/ ^6 ]! |" j& m    string s1;
, f7 |; ?& B- W1 l/ S7 W, ?    while(cin>>s1), n3 _* S2 P4 Q' ?
    {: J/ a  p7 r2 J1 u
        istrstream isin(s1.data());
2 a" a7 @+ T6 H$ C        double d;
4 O" K1 d+ ?& [, {7 O6 n3 J2 l, y        if(fy_Exp::GetExpValue(isin, d))
; _* z, _- s1 n8 f  a        {3 U8 ?% B* d. s
            cout<<d<<endl;
! A$ u) m+ v* k9 J; @; }        }/ ~% `, ]& M$ c* Q* _
        else
+ w4 i/ v) i$ ?5 k        {' m4 y, {7 L) A5 b( R( o$ m
            cout<<"ERROR"<<endl;
) _, ~  j' ]$ ^1 q        }
' y) e/ R: l- d    }# j8 p. w( ]( h$ h+ J+ @7 k- g
    return 0;9 _9 ~8 |9 O9 ?& P  h9 ]
}
% h% V+ H0 U5 ~% U- J6 c$ ], Q" Y5 i2 ]" y4 J& ~

1 W5 `8 U/ }0 I然后编译执行就可以了(*^_^*); s0 w& j: N8 E* v0 a" v3 |
其它:TC++上一定编译错误,不保证在VC6上也能通过编译
' l5 P, M, K4 L8 \6 u      建议使用VC7或VC更高版本,或者使用GNU C++编译

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