返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
6 n$ h! t) D' q' B% e+ u1 G) k一个很方便的函数模板,可以并且只可以计算含括号的四则表达式" W# ~7 u4 T0 I4 k+ P" t/ }
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
+ T: [) r4 P, z+ V) o# D: h& \参数解释:
7 e7 r; j/ _$ X8 f) r% ?, A4 {9 yistrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
/ i( B  }5 S  o0 VnReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
; r3 Z1 P# W# b/ w2 @9 r返回值:: v9 S- a/ I- A- W# R: `
返回非0表示计算成功,0表示计算失败有错误7 v  \5 M- J0 ~& \8 ?6 _

* ]: \9 p$ p, I$ t; z7 y- Y) V* M
1 A  I# Y6 ~; I6 S; I4 d
! p: |# c2 g; |, |8 x" i8 r! D- H程序代码:
! X% _4 M! w& E7 ^5 D) @  b, D# l6 }) O' x/ z9 H  V
namespace fy_Exp{3 H/ r+ ?4 j5 i& ]6 e
namespace {template <class _T>" h, Q+ e) A' A; r3 x
inline _T GetExpValue(_T t[], char& csym){: f  D$ q, z8 e; t* x: Y% Y
    char c=csym; csym=0;
( D8 W; ^2 o6 }  D/ H+ {    switch(c){
/ b5 M) v( C+ `    case '+':return t[0] += t[1];) S' m9 V! `* j: Z# R3 L8 y  L, `4 O) O
    case '-':return t[0] -= t[1];+ U8 d! F3 _0 m2 p  i. r) h
    case '*':return t[0] *= t[1];
2 }$ L$ |7 t  }6 \& S  D( V    default: return t[0] /= t[1];//case '/':) o6 ^0 u  T8 S
    }
8 c4 \7 C3 r, [' _# O9 ^}}% \% d4 H& }3 ?. d/ y) i
template <class _T, class _Tstream>
/ v- [- m0 j% Z: }/* _Tstream: inputstream, _T: get return value
* \! d2 `' Z! u* Return nonzero if get value successfully */* E  s. |/ w! h% x7 f. b2 B
int GetExpValue(_Tstream& istrin, _T& nReturn){
5 U* g1 E% r6 ^7 e/ `    _T t[3] = {0}; //雨中飞燕之作
  o$ _0 Q+ y: q6 [2 w3 S: c0 }    char csym[3] = "++";# M6 v2 R4 r0 g- A; q2 c
    int nLevel = 1, nERR = 0;$ L/ Q: t1 e5 E5 I- v7 ~9 B
    if(!(istrin>>t[1]))istrin.clear();
# U: `. C* d/ z) o+ H/ w    for(;;){
, V( Z4 u5 L, J7 [        if(istrin>>csym[2]){
, N) M4 y1 E; F0 P1 S8 m            switch(csym[2]){
8 h0 h  O/ u+ i! H0 w) X            case '(':9 n4 m  v: |0 k/ d6 G" S
                if(!csym[1]){nLevel=0x100; nERR=1;}else7 G" q. ^% B- p
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;6 {. V" |2 t) x! R( D
                else{nLevel=0x100; nERR=1;}: J+ g2 D5 ^) U* c
                break;7 c. u8 b) v( E6 Q! O
            case ')':( b6 z% O( E. M0 {
                {nLevel = 0x100;}break;3 a9 o4 K+ B% Z" C" e6 ~
            case '+':case '-':case '*':case '/':7 n7 e8 t/ q# w: n# W) h
                {csym[nLevel++] = csym[2];}break;
6 d1 \' M: g$ v" X# a+ H" M            case ' ':case '\r':case '\n':case '\t':continue;
" u8 m; {2 n6 @* K+ u$ N+ Z, W: f9 J' u            default:$ u+ z! r0 y) h5 W
                {nLevel=0x100; nERR=1;}
8 I! l6 j3 I* b9 R, K            }" x; A0 ^3 W$ e! e! @0 B* p+ n
            if(nLevel==0x100)break;
6 @% m9 f9 |, p( K4 ]            if(nLevel&0x10 || istrin>>t[2]){
% \. t: f. J; U$ \1 u  g0 G' v3 M                nLevel &= 0xF;
$ Q- }- d0 L) R! \4 X6 ]* {                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
8 M$ A9 c# s" w% q8 p                if(csym[1]=='*'||csym[1]=='/'){
7 \+ e' S/ k6 H/ I2 {' Q                    GetExpValue(t+1, csym[1]);$ b4 ~- D4 G3 Q5 T: Y
                }. j* z$ J; g' H, }& V/ O2 F+ ^+ M  i
                else{
3 ^! @! X! T. U5 S% Q; f/ \8 G0 K                    GetExpValue(t, csym[0]);0 i: c8 r6 [4 w: ^
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;& b9 d% |, f( ~1 g& `+ Q- f
                }
) D# K3 O* v. I$ i$ i6 \* ?                nLevel = 1;
: Z6 G7 c$ }: w+ g( X1 F* j            }2 T4 z7 L/ C- ]5 W
            else istrin.clear();  ]/ r9 U- a; Z( y5 o) V
        }
7 k7 ^6 k. I) b: N% c        else{nERR = -1; break;}0 _6 M. K- Y3 \! L; p" v9 J8 v& U
    }
5 r5 s4 X4 ~6 G( |* [3 L    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);, S0 {% d6 k8 \4 G
    else nReturn=GetExpValue(t, csym[0]);
. s: _  i) q: p    return nERR==-1?1:0;" H% L" g) o" Q- x8 A
}}
: g; d1 P5 W8 M2 N7 \/ b% R7 `7 d' J5 z6 K: Z5 B& q; x8 y0 W. n
% h2 o2 y% |) k! K

% s1 e3 U% q5 N0 B/ q- o  t函数模板使用示例:
4 G0 q/ E' T9 T在以上那段代码的后面加上以下代码:
, C) _. Y( {$ T% @4 ]+ Q7 ^1 f" o: M. Z% ]1 ~6 s9 P8 M- D

- _3 U+ J$ y; k7 U( V8 t
' N9 V, ^9 T  S1 f" N" m程序代码: 0 ^7 [3 e  h8 v. u: B

; c1 H' s7 N, c& Z#include<strstream>. H# d: @( d9 i
#include<iostream>
$ F0 [, I+ b6 N2 }8 |/ P2 ~#include<string>
$ J9 |3 q' b+ J( busing namespace std;
+ l5 ]' ]/ }- U* ?int main(void)& f/ g7 o, s8 ?8 `+ A, x
{
: ?9 B; r% e( c. c    string s1;/ A; }2 \/ U* B1 f; e
    while(cin>>s1)
( {" T4 X% N, A7 v3 D1 k    {
4 w4 f; S' {9 e6 c7 U' `2 g        istrstream isin(s1.data());. d% r& ^% Y4 Y6 V. J
        double d;4 h; _- C; L% t; M
        if(fy_Exp::GetExpValue(isin, d))
, W7 A( b! B; ~6 K6 H3 i7 q, r: X        {
+ U) h+ O1 ]8 i, g            cout<<d<<endl;
. Z1 Y' q* |) k; y  Z  T3 `: f0 U        }! B" O: S  C, ]6 z$ S1 H7 ~
        else( B' D- K' F% N7 p9 K
        {
; T5 y& h! B. B8 o1 Y            cout<<"ERROR"<<endl;% a- ~) ~* w+ [" t; w/ j$ E
        }5 A, q0 _" }/ M5 E; j- R
    }
$ a6 g4 m" I; G" W& @, A% a4 l    return 0;; O2 a! O- ~% R2 C8 \; V' K) c
}
1 m  k/ w. v& I% _0 r
6 s- K7 C. u4 e1 q; B* _; `$ E( a+ |9 ~) C# y
然后编译执行就可以了(*^_^*)3 J% ]* p4 T) z# o# j' n
其它:TC++上一定编译错误,不保证在VC6上也能通过编译) c. t& `3 s1 r5 G6 ~; t
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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