返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
. D3 A. e6 x& C% \" z一个很方便的函数模板,可以并且只可以计算含括号的四则表达式, z# x4 p3 W, k1 I6 F- D/ Q  r
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)$ f+ @0 }$ `  B) q7 A* k
参数解释:) v2 ~5 n. k: Z1 ?) ~
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流2 d/ }5 b) h6 f- [  G" h
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定+ t* s3 a- Q' I+ {/ L
返回值:0 Q6 _- a$ E- ~
返回非0表示计算成功,0表示计算失败有错误* ]; E& n' i- ]
) ~) x' L- V0 ~+ S# z. ?. M
) d6 \2 n3 o, }) ^7 @* I7 J
8 g# e' X- \9 P! r- J5 a
程序代码: / E5 l& ^0 q% Q5 V

1 `1 `0 W  ?3 Z2 ^namespace fy_Exp{
: U; H" h) {, m7 O  W. f9 ]namespace {template <class _T>
' \9 I, C5 u1 a2 L/ L1 ninline _T GetExpValue(_T t[], char& csym){# |( _) n: C5 ]. O" K; e7 k
    char c=csym; csym=0;
) Z5 j7 {: X9 S8 [    switch(c){: s5 Y" ^" Z( r
    case '+':return t[0] += t[1];( t( O, i8 e9 @' V( G
    case '-':return t[0] -= t[1];
  b* R( L7 s! @/ F1 H( [    case '*':return t[0] *= t[1];) _* i1 R$ u) E6 |9 H# L
    default: return t[0] /= t[1];//case '/':
/ l( |3 W8 Q, p, U6 t    }
  p5 ?4 J8 o* @& h}}2 T2 B+ Q5 h0 b4 F" a! \3 e" F
template <class _T, class _Tstream>
$ n$ e6 E" V" ^# K! x/* _Tstream: inputstream, _T: get return value- b$ ?/ ~6 D4 }& Y8 Z1 u$ |
* Return nonzero if get value successfully */
$ s  {) W2 |$ S- vint GetExpValue(_Tstream& istrin, _T& nReturn){" X5 ?* n' ]# u
    _T t[3] = {0}; //雨中飞燕之作
# R1 T0 z- E3 |4 F8 n    char csym[3] = "++";% a# j, v5 y2 {) o! _
    int nLevel = 1, nERR = 0;
6 e, H7 h% Y& K5 n" O' s: n    if(!(istrin>>t[1]))istrin.clear();  T% C: L& E7 g! G; b$ k+ ?
    for(;;){6 g: ^7 _# o, d4 H/ a( Z0 l& J
        if(istrin>>csym[2]){5 d: o' m2 A7 h% K
            switch(csym[2]){) J/ q9 Y/ Z; Y
            case '(':/ E) f: X4 v4 ?: X; d
                if(!csym[1]){nLevel=0x100; nERR=1;}else+ f( b& ?% ^5 p% ?' p
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;6 h: ~' ~3 f" ?" w' o+ ]
                else{nLevel=0x100; nERR=1;}: t8 s7 T! J6 |. U/ b
                break;
. w1 p, m# ^) I  @            case ')':
9 Y" H- |) E4 g1 b( g) q# [                {nLevel = 0x100;}break;5 O& X6 ?: y1 D) i' R* Q/ {! h# N
            case '+':case '-':case '*':case '/':' I- c( D7 X  y5 u  Z
                {csym[nLevel++] = csym[2];}break;4 O4 |- u) i2 }% i' b
            case ' ':case '\r':case '\n':case '\t':continue;
- k* z% _/ V$ X! P            default:, a+ v) P. ]5 q: z
                {nLevel=0x100; nERR=1;}
& G( A5 o% f( g( T, B* N            }9 L# Z, Y- t" B0 h" R
            if(nLevel==0x100)break;: {1 k: a) l+ }" o. z
            if(nLevel&0x10 || istrin>>t[2]){) B2 i4 R0 h! G7 M8 h
                nLevel &= 0xF;6 B: ~5 C0 p9 y! E# F
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}3 a. J% O0 M. V4 |5 B8 w( c# O1 R
                if(csym[1]=='*'||csym[1]=='/'){
# ^' d$ r; D) a* t6 E( p, q3 z" r4 `9 i                    GetExpValue(t+1, csym[1]);
1 V5 s2 I/ H, r3 ]                }/ q6 S; g; A. ?  _9 d
                else{
) f# J# T& ?' k3 d9 m0 u                    GetExpValue(t, csym[0]);
" Q' d5 b2 B# l. T- q. b                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;" o) j- Q9 Q9 x& ?  y* F
                }: f6 I& d! S; Q+ h  [
                nLevel = 1;
+ e  e( P" L" f7 g/ o            }1 T: w4 D3 s5 P, N6 Y
            else istrin.clear();* |2 E+ j! }; z  ]$ r0 W; `, G7 }0 H
        }
& o) E: l) }7 h3 ~7 q5 E) J        else{nERR = -1; break;}
  c' r. P& R1 W3 R8 R" Q4 @    }5 Q$ Y" j% S% E
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);: [2 X5 D0 w- ^# ?3 X4 B! P
    else nReturn=GetExpValue(t, csym[0]);
1 H1 J+ k2 z  s& t; O# v3 K    return nERR==-1?1:0;
5 c) V5 x0 a. N& V, \. P5 R' f( }}}& a3 c& q; {3 }5 _

* ]! o" g5 X' O- }6 W% O' U+ Z4 n) i4 R8 L! R

2 l3 N' W$ [8 l* X, b函数模板使用示例:
1 `1 N* L. Z; i- G- n0 M2 D! R在以上那段代码的后面加上以下代码:4 p8 W! V" b( v' Z% `
; I# y; N* Y; a7 M4 e

% [+ R0 L$ F' h* @# ]8 Y: d6 ~
& I. k: }7 ~) e5 O5 w! r% S程序代码:
$ v. g) v" x) Q+ I3 M1 \! ~& d& u: b( [+ m# t+ C& K
#include<strstream>' o; e; Q+ j7 [. x6 F' k6 A6 n* N9 e
#include<iostream>! `% E% G' ^* y! i: i: I
#include<string>7 B! X% R, Z2 U, `! b; L
using namespace std;! F# K0 X( h$ _9 n. w/ w
int main(void)
1 u" h$ d0 N/ Y% ?{& ~$ `7 ]$ k  S
    string s1;. G% d1 M' i0 _0 R
    while(cin>>s1)( U, a% @6 N% u* Q4 q
    {
& n6 R# C/ E. a* ^        istrstream isin(s1.data());. v0 b: ?0 E: L! I+ l# j
        double d;/ O+ o1 U  V. l5 ~5 o8 _
        if(fy_Exp::GetExpValue(isin, d))
3 _- y& p2 T; s        {3 u2 w- `; @0 w  `( t8 G4 e9 L
            cout<<d<<endl;9 Y; l& ^4 A( P4 H
        }
$ V/ P! O9 L+ H' @7 x! V: f" t        else
* Q8 L; g; U/ R        {5 D8 C0 ?9 Z- s( |- S' Y6 \
            cout<<"ERROR"<<endl;
1 T: T! H% L$ R/ g) j$ }        }3 a3 w: E* A: s3 m. b
    }$ o' L2 g5 m; Q4 _# Z
    return 0;& i- [; j! I% @; J  Z
}6 h( B, m1 O# w6 v  \
: f* ~. K; V3 j5 w2 g6 X% w, X0 |

4 P5 m  |  G5 s4 ^* `3 q* y5 N/ _然后编译执行就可以了(*^_^*)
0 _3 U6 l& A5 N! |! C2 f其它:TC++上一定编译错误,不保证在VC6上也能通过编译
0 y" ~6 S. I; H1 r; ~  ?      建议使用VC7或VC更高版本,或者使用GNU C++编译

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