返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
9 v. v' R  ^' g: m& C一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
  c" B5 y1 C4 `! `- X8 _只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn), F& ^; F: M2 [# U  H2 b
参数解释:7 i/ K; Q, N( Q
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
* f5 G. N7 l$ s+ w0 U; Y+ V8 cnReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定' D# D) ^& f0 P& G( z
返回值:/ ~! b! d! H( a! Q
返回非0表示计算成功,0表示计算失败有错误( m# c2 e5 q5 Y8 ^$ M% V5 h/ P

) L0 i, K, z/ t& p
% l3 U/ Q3 h# w0 v5 F) B5 I
* X$ s, j8 l3 }程序代码:
# e5 ^, ~8 m3 \" f* b7 B8 l5 @
% Y1 T+ K3 T! k7 r5 qnamespace fy_Exp{# `8 f4 {% w. {5 l. |% R: ]: G
namespace {template <class _T>3 A2 g4 Z# \) H! P8 G3 ~% k5 \+ U
inline _T GetExpValue(_T t[], char& csym){% N+ \- y  ?$ L4 K
    char c=csym; csym=0;- e" n  S+ `8 t1 X7 D+ x3 L' k
    switch(c){" X2 J0 [9 ~' c* |
    case '+':return t[0] += t[1];1 b* ?3 q4 T! U4 X* K' H  Z
    case '-':return t[0] -= t[1];9 P9 o( U# i, j: l
    case '*':return t[0] *= t[1];/ G# |  E; v( z6 q0 i. j. R
    default: return t[0] /= t[1];//case '/':
0 b/ C# J, B. m- I! N! m# P3 M4 Y    }0 e- e/ Y) `1 `4 S* ~- O- Y
}}
) f$ A( n/ o' Ntemplate <class _T, class _Tstream>/ o2 Q/ o0 C0 j% o
/* _Tstream: inputstream, _T: get return value
( z/ H" @& ^! r- T( k* Return nonzero if get value successfully */; d( v& B7 G& H8 ?' s, {. E7 l
int GetExpValue(_Tstream& istrin, _T& nReturn){# {+ k2 ?3 n  `+ _# c3 G/ D
    _T t[3] = {0}; //雨中飞燕之作' ^5 y  o9 C3 y% n
    char csym[3] = "++";5 X. `6 @6 z! e- i/ ?& X, Y
    int nLevel = 1, nERR = 0;3 N" p1 ]9 R) G6 A) U5 s6 A9 {& R
    if(!(istrin>>t[1]))istrin.clear();
4 G4 L8 y5 A# S% t  k) H! f: V5 n( v    for(;;){% l) j) `  C9 E$ V  m- ]6 `. l
        if(istrin>>csym[2]){% r. }9 [' h* Q1 b
            switch(csym[2]){: J4 C) m* W3 B  V, ?* W$ a
            case '(':
: M6 N' ]( k& J& ~7 D' X, n" T4 K  N                if(!csym[1]){nLevel=0x100; nERR=1;}else$ O* E+ d* d) p6 Q2 F
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;; X  n5 {; ?9 t+ s7 ~- M
                else{nLevel=0x100; nERR=1;}1 V- w, l& `/ X8 e/ u# Z# g2 u
                break;1 p' j. i2 M9 {7 b) y4 L
            case ')':' {+ I) z: y) O
                {nLevel = 0x100;}break;
$ X% J2 C9 \& j/ {" T4 i% [' |, e            case '+':case '-':case '*':case '/':
5 r# }4 d4 D! [9 y$ w1 W5 \$ |                {csym[nLevel++] = csym[2];}break;
( ?! ~8 u& z; c7 ^) `. _* T            case ' ':case '\r':case '\n':case '\t':continue;
1 a8 L- g( a* ]! k# `7 x* R            default:0 [' @% w, C9 ]
                {nLevel=0x100; nERR=1;}
0 f. `" U+ Q9 g( b+ t5 R7 ?            }
+ Y2 q0 L' A1 g) F0 h) _, A% @            if(nLevel==0x100)break;1 {/ L  y2 A5 m! x3 z
            if(nLevel&0x10 || istrin>>t[2]){! q1 j5 o. h! M* _( w$ w
                nLevel &= 0xF;
6 C' d5 T- c$ s                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
5 U7 S& q; B2 ^. ~. S. a! ~9 ^* n                if(csym[1]=='*'||csym[1]=='/'){
9 Q" u8 ]$ O  j) M- g                    GetExpValue(t+1, csym[1]);  e+ P  Q( i- n; [+ Z
                }7 r: u, J' I0 v3 Q+ A( V
                else{
, ~4 E% Q( n5 i- @* m) E7 Y                    GetExpValue(t, csym[0]);! f4 V8 h2 g& H# v( B; U( q' w$ g
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;( t9 F& W9 \3 p
                }8 J/ v0 J4 M( J' c) R# P& W
                nLevel = 1;
& R: T+ D! a' Q  E) f4 I            }; v7 D6 N8 d  l9 f) `
            else istrin.clear();& {: M0 Z) L  D5 X. x# ~- [
        }
. Q( I$ [# R4 E  _5 \$ ^" X+ |' o        else{nERR = -1; break;}2 l6 B1 m* h* k- v9 _0 T
    }
4 q- f9 K; V& {5 [$ N    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);0 g2 e+ T7 C( H2 H
    else nReturn=GetExpValue(t, csym[0]);
' e* Q# k, \/ q8 U    return nERR==-1?1:0;5 `/ h6 b5 }' i
}}* e7 K. `6 P  k1 }, p5 A! w. U3 {

( T6 O7 x; w- K1 N$ P
. o# h/ J6 C% ^- ^4 o, a, v5 \& P
函数模板使用示例:
( |- n7 H- J0 B& D在以上那段代码的后面加上以下代码:# d/ |6 E9 _4 f* ^0 n7 p, h

+ q* _, x. N/ t 9 I6 L0 U$ B, n6 Q; @
* `. t1 u% q% A
程序代码:
% j  ~$ L8 A0 L& \+ K. U) l1 ?7 q  f7 H3 r9 ]; g
#include<strstream>( o" N: L5 p' }( R" }* o. ^$ |
#include<iostream>2 A- C+ B- \" D$ E# M, F% x
#include<string>
$ V& t- l" o" ]# uusing namespace std;: R3 t# l9 v; }* Z) u
int main(void)
! F) h, X. {. K3 ?! N$ U: ]; ^  u{0 G9 P( a  N( K9 d: L
    string s1;* e7 x1 D( {$ o5 `& i) T4 s
    while(cin>>s1)
9 |$ N* b6 v; P* h    {  h. h" A; M8 j# X* `! D
        istrstream isin(s1.data());3 O7 \" k. f: B! [8 D* K2 c$ i
        double d;
# a+ M+ _3 f* `, p8 l9 |        if(fy_Exp::GetExpValue(isin, d))1 ^9 ]0 Q3 n# e2 d4 ^. A' H/ _: I( u
        {
' [1 e% m9 W6 s4 h' L            cout<<d<<endl;# z4 H) ?. ?% M* i9 P
        }
5 Z) ~/ K! X8 R4 B        else
* Z$ X8 h: D) l- [( G        {
2 S2 G' s% Y0 p8 o; G2 V% _$ [            cout<<"ERROR"<<endl;
7 r6 V) q! m) I3 S. s2 m/ }; w7 P        }+ }( O  y6 ~! q& H+ y4 r0 r
    }8 p2 f7 A' x& |
    return 0;
7 p7 B& H& i; L}
$ O& [9 n/ B, s& B0 W& w1 y6 b7 S4 W! P$ k0 D" F" j9 S- |

( R3 J$ R+ A) ?! X! X然后编译执行就可以了(*^_^*)
$ a; d9 |2 G+ `& }其它:TC++上一定编译错误,不保证在VC6上也能通过编译% A  |6 `7 m0 G9 C5 `2 N2 }
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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