返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,  Y( Q# V& }( k! q
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
1 F1 P: H/ _1 \( m- a- x+ ~: o只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn). ~6 L9 }$ v% N3 j% }- i
参数解释:' @+ T5 X1 y. k$ W! }
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
* k6 b# {0 }/ x# p9 O- O3 a8 G5 rnReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
9 k8 A/ S2 d' B0 t+ d% _* |! R返回值:# {; p" Z$ N. _/ S- k- F
返回非0表示计算成功,0表示计算失败有错误2 L, W/ l$ `2 F' G1 Z; T
( ]) E# b, _0 v" K" `) N
' M# w- s8 ^% V$ p- k8 Y7 }# C
& R9 d, Y* ~$ }& @  v
程序代码:
0 ?# b$ r, F  [. ?% [
5 r) z0 I$ I  f9 m/ wnamespace fy_Exp{3 ^' u! k5 @0 u+ W% u7 D9 E* Q+ ^
namespace {template <class _T>/ s3 A/ X) r: f9 c" Q
inline _T GetExpValue(_T t[], char& csym){4 L1 ^- Y8 @4 o; ~. i
    char c=csym; csym=0;
3 q4 N) x% n6 t( {( d& ^$ l    switch(c){- F+ a1 k7 W  h4 R! R
    case '+':return t[0] += t[1];
* ~  z/ m1 G& }. d$ p* D! O    case '-':return t[0] -= t[1];4 [- k1 U" ?* d% I5 _7 A6 q* v
    case '*':return t[0] *= t[1];) l8 p: B5 x8 D) ]7 e
    default: return t[0] /= t[1];//case '/':% ?0 E6 j( d2 [  a$ ^
    }
1 ~3 y8 i3 @  ?5 P" A) _$ B$ y}}; S/ q. L9 ~' e6 o% d: O9 F
template <class _T, class _Tstream>
6 o) Z* M0 D# o1 V& N# F" j0 w/* _Tstream: inputstream, _T: get return value! {1 f; m7 g6 R7 R: g8 q% V/ D
* Return nonzero if get value successfully */# L6 a4 A) N2 [, [  A
int GetExpValue(_Tstream& istrin, _T& nReturn){
7 X% W0 e6 [, R$ |9 q    _T t[3] = {0}; //雨中飞燕之作
$ V, I% d  I' N# n    char csym[3] = "++";
5 k- w' c0 l' n: l2 l    int nLevel = 1, nERR = 0;
) b0 F& X: F- `3 W; F4 S    if(!(istrin>>t[1]))istrin.clear();3 ^" v7 T: ^$ c1 n/ z
    for(;;){
: X/ u- r* c9 o2 N        if(istrin>>csym[2]){6 q' @7 p! ^% |) e; ^, R
            switch(csym[2]){
8 u' Q# Y# K! _2 b- a- O* L            case '(':
0 J) z) ?8 d9 e, Z1 K2 p                if(!csym[1]){nLevel=0x100; nERR=1;}else- G- ~9 B+ j" f6 C$ n
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;( `! _8 K2 b, A, {, A; Y
                else{nLevel=0x100; nERR=1;}
! f$ H$ o. K. k# n& q  q0 K' ~/ }                break;1 S# s% E% X  R# e1 u; ~$ L
            case ')':- D3 Z; T1 F8 _
                {nLevel = 0x100;}break;% E( o* f* w) W  A
            case '+':case '-':case '*':case '/':( @% K) I- M. Y& u1 O  n
                {csym[nLevel++] = csym[2];}break;0 c( b+ a, @" u0 w
            case ' ':case '\r':case '\n':case '\t':continue;
3 S% e1 F1 C- U2 g* \            default:
9 M" H  Z- D& |; P& ?1 ~' t                {nLevel=0x100; nERR=1;}
* J0 a: V/ ?& n1 x            }
: |# I) q0 a0 m6 x' u            if(nLevel==0x100)break;% A3 ]% M0 y2 w* P0 G+ V+ h. ?3 }' ^
            if(nLevel&0x10 || istrin>>t[2]){, z2 A. W( t" x: Q
                nLevel &= 0xF;5 W) }0 H3 Q. ]9 Z+ A/ `; S. V
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
7 F1 o4 n( s) ^# K' H3 k/ }                if(csym[1]=='*'||csym[1]=='/'){
9 k  s7 q  E7 D% b: ^- v; Y                    GetExpValue(t+1, csym[1]);6 {2 I% {3 d5 e; i0 j. b
                }
, y. V% Z$ z9 @/ P/ E                else{
9 V7 O, I1 {% p- Y0 w                    GetExpValue(t, csym[0]);
9 j* _; e5 P. b$ p" x/ p0 U: R                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;+ A5 |8 K) w- P' v& P
                }* }) v  \4 w& G6 u$ }# y
                nLevel = 1;
/ t% h# t5 c8 M8 w            }( [$ |6 |' m" Y* \3 ]6 U
            else istrin.clear();
0 i* i! N( T6 ?# h$ @        }% y1 v: r1 e* H; f
        else{nERR = -1; break;}! _% q; `$ N+ e$ v3 v
    }1 k# s0 {& z* ]- Y/ {% O. O- j
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);/ `  q: L" }9 v& q4 g5 B
    else nReturn=GetExpValue(t, csym[0]);) H6 q  \; g# U- T1 `  _% e
    return nERR==-1?1:0;# i% x  z* g' c2 |
}}/ n) C  f3 w& J  e
5 K$ V) |* d. t- f) v" C

2 k- X! S. F* K0 ~$ k$ Z8 ^
/ L, |" V; ]7 H) M! |函数模板使用示例:
* U+ r9 G+ C& g' f5 d( I. j! ~在以上那段代码的后面加上以下代码:
7 r6 b% m. g9 v- P, j$ N6 u
/ i) e+ b! Z6 M- r 4 F# g; t# X1 @( L6 l% q

: Z5 {+ y9 _- k+ ]: L% O! b5 P程序代码:
. S# k. w- }. m8 j
' z+ p" n( H. E& X6 C8 h#include<strstream>
# d# Y) r$ X; O+ C( l/ |0 G4 N#include<iostream>) M3 |+ b: r6 w) f% ~
#include<string>' f: `1 J2 b" w
using namespace std;
, D/ O6 Q. W- X1 g  {int main(void)
2 F2 y% A; S( U$ F2 ~5 i% J; t  ~{- n+ C& K4 d. s5 c
    string s1;! A' o1 a" f" s6 r  Q) C
    while(cin>>s1)) N8 b! M3 t) E- k; n7 }
    {
* ?0 E. h+ Q7 t: h/ n% s! Q% a        istrstream isin(s1.data());
! E3 Q0 Y% e9 B' a. ]+ y5 g- E        double d;
1 ^8 S' y8 @* x5 ]        if(fy_Exp::GetExpValue(isin, d))+ d0 Z0 `: v8 Z) I- q6 L, f, L7 _
        {9 R: l& C/ G7 D8 C
            cout<<d<<endl;
* W! Q- y4 h) E# _        }/ N& p  J8 T. X8 m% v
        else
4 u' ~* o4 c0 _; [3 K        {
9 K2 S% \0 ~  s4 F            cout<<"ERROR"<<endl;6 I8 x4 P* b7 o8 h. ~$ \
        }7 O( ?7 M) N! }, G
    }0 r) ]: u$ V0 l3 z: h( E# O! e. ^
    return 0;5 l, i* h3 r: g+ ?$ P/ H
}
; b1 N" X$ \5 X; F# j" i
# ^" \' A* {6 ^+ \5 o+ m( U- ?5 o9 K1 @7 G" q/ Q
然后编译执行就可以了(*^_^*)
  x1 n% }7 q( d% h  g# B4 ]( r其它:TC++上一定编译错误,不保证在VC6上也能通过编译! M/ }  b. b8 j. D
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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