Board logo

标题: 一个计算四则表达式的模板 [打印本页]

作者: zw2004    时间: 2008-1-21 20:17     标题: 一个计算四则表达式的模板

在9月8日那天我特意编写的,给大家分享的,
0 Q: ^' y) z( m" e( ~' i2 N+ l一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
8 P$ Y+ B  v& Z' R1 G1 A只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)# h$ d; _! w3 [, C1 m% N
参数解释:1 q- ?) D# g! I0 _, O: x
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流- }0 J$ `; }6 ^$ P( \  t
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定5 {& C  ^* b2 `! G; W0 j, ~
返回值:) {" z# B( o; d# k$ @
返回非0表示计算成功,0表示计算失败有错误
8 U: G. f2 i; }! F6 b! N4 T3 n5 d+ ]* M* O+ K8 f/ j
6 B' L: G3 z1 o& ]+ u0 K8 e
/ ]* P3 J7 B  `, x, n9 X
程序代码:
0 R4 T+ [) W6 i9 |  P  ~. V! |
" F8 m( n  i5 q. B2 h: L& `namespace fy_Exp{# Y9 K3 ?: |' I/ G
namespace {template <class _T>
7 @% c+ c  U, v+ linline _T GetExpValue(_T t[], char& csym){6 l$ A. W) q: F7 n
    char c=csym; csym=0;
' u6 O$ F* H7 @8 Z/ D' _; U3 T    switch(c){, d0 _+ y! ]& b4 M! N
    case '+':return t[0] += t[1];8 I; \1 @0 M7 s1 ~
    case '-':return t[0] -= t[1];$ E" k( e. Z8 h0 W% l. X
    case '*':return t[0] *= t[1];
* a4 j2 @8 X" Q- C3 [" H) C    default: return t[0] /= t[1];//case '/':
- `9 O! {* R! j$ B3 E$ U* {0 O5 Z    }
3 L0 m- c& M& K  Y( N$ O9 W}}( ~: q1 T$ _% ]* K+ r
template <class _T, class _Tstream>
# Y8 |$ U( d3 U/* _Tstream: inputstream, _T: get return value) k4 s% w% W* Q% w: ?' a3 V
* Return nonzero if get value successfully */
5 g, K. E# ^" V. Rint GetExpValue(_Tstream& istrin, _T& nReturn){
7 W8 Q$ x* p+ n7 p) N! E6 L    _T t[3] = {0}; //雨中飞燕之作
2 v# n, \+ t; d$ R6 x5 D6 R9 _    char csym[3] = "++";8 i" W+ X) K$ H8 \# M- r
    int nLevel = 1, nERR = 0;
9 {2 n8 `1 W7 k: [: {- s    if(!(istrin>>t[1]))istrin.clear();
# B6 [( x: m2 X; I    for(;;){2 X7 x* W# f9 x$ m# L3 \( Z8 F
        if(istrin>>csym[2]){/ M. u' G: M5 g$ o; E
            switch(csym[2]){+ s+ r0 S" }" ^2 l. c/ g/ j$ K
            case '(':
7 V3 [, s; B' P& @& j* w                if(!csym[1]){nLevel=0x100; nERR=1;}else  _. ?5 g/ G8 |
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;9 _1 o* M2 b! q+ b2 M
                else{nLevel=0x100; nERR=1;}2 m0 e! e' I3 A- n& }$ @
                break;7 K! n- }0 m1 w7 m% s! g) m+ j3 s
            case ')':1 X7 D5 I' [/ C# a& t0 o3 z
                {nLevel = 0x100;}break;
: b6 T# n# J2 _4 [) R            case '+':case '-':case '*':case '/':; Q* o5 g0 O2 `/ ^2 Q& j
                {csym[nLevel++] = csym[2];}break;4 B8 V# E: m4 `/ Y! a2 c: n
            case ' ':case '\r':case '\n':case '\t':continue;
& o: K9 }. ~7 D5 X0 }! P            default:
$ u- m1 E9 e% ~8 @$ u                {nLevel=0x100; nERR=1;}
+ }  {" x% W- ^+ u! b. G% l            }+ \/ e2 w' P) ~/ @8 d
            if(nLevel==0x100)break;6 u; @  c8 h* l; _
            if(nLevel&0x10 || istrin>>t[2]){2 y6 J6 G5 t+ o, G4 N
                nLevel &= 0xF;
- Y$ Q9 x9 h2 \3 D+ ?                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
4 V8 o. |0 g) s7 U. n. R* _                if(csym[1]=='*'||csym[1]=='/'){
7 D- g& {7 ~* J! S                    GetExpValue(t+1, csym[1]);
$ |. a+ v# y# S- L9 g# g: U                }' ]8 g; T: N. o- \, \0 K4 L
                else{3 Q' l' y, O+ F4 H+ }. |- R
                    GetExpValue(t, csym[0]);5 ]8 W( |6 l2 n) e; w
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
" \9 x$ j; a. b. u+ Y1 o                }- B) f& y! w: n- Q% h5 u
                nLevel = 1;
3 x' _! Z( e9 _! J) {5 ]            }
: E' w% W1 o: n# m( X+ v0 y            else istrin.clear();
) M4 k7 @: M6 \9 r4 J( r2 W        }/ p# l) E: t, m0 Z/ P4 L' I
        else{nERR = -1; break;}
& i- \$ _9 {8 J$ W4 i" U) @    }
; O* w$ t# n# X    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);6 v' N) L0 N2 m( q4 x
    else nReturn=GetExpValue(t, csym[0]);
- |% F5 v* [8 @8 D    return nERR==-1?1:0;
+ e# T# ^/ l5 x' Y+ W' M}}
( @" B+ Q. i! k) P! _  `
! _6 z, m4 A! s5 u: G0 Z
! y/ D# v$ J! ~. f3 C, I4 |+ J8 D* J' X' W
函数模板使用示例:4 ]* C8 i. d$ G- h! k
在以上那段代码的后面加上以下代码:: p& a8 b5 o, q& A; `3 I9 y: P" A1 D

9 n% {" M2 \/ {0 h/ w
. W7 P- b6 D) ?9 h* V' |9 J! t) S6 w5 T' ]0 N
程序代码:
+ m: ], N2 d. X* w2 I' N6 `* \8 u4 r8 B
#include<strstream>8 B6 v4 F1 t2 v/ S2 |: w/ P
#include<iostream>
% @6 ~9 y3 n# N( ]5 S#include<string>
; e4 I. p; _/ k* H: qusing namespace std;3 n9 C0 v9 ?; J& `' O
int main(void): e0 |' I3 l; D' r( i
{
" D; j5 o$ [/ E, |) {- m8 R    string s1;
! F$ d# z& G9 V) j$ [; c    while(cin>>s1)
- W8 Z# x- r5 v! |; o; ?    {# t; k" Q1 a/ Q' E7 }6 D1 ?! h6 ?
        istrstream isin(s1.data());
( ]) W% ]( |/ H+ Q+ O, I$ t% ]# o        double d;$ X# x( v  m1 g1 k) O% P7 k" f
        if(fy_Exp::GetExpValue(isin, d))
: l) ^) \- B3 g; B# X/ r- o  `, b        {
7 c4 `# F$ |7 B' x% q* p: e% U            cout<<d<<endl;0 L: D+ `8 Q5 `- t2 e
        }1 y. N6 W6 p$ u+ L% ]
        else7 W5 \8 I$ f- Z+ ?
        {& B3 F3 g, l6 s; c  b$ o+ M) n1 R
            cout<<"ERROR"<<endl;7 @$ i" P& F, N+ h
        }! K0 Y* d& b3 @/ y) H/ t0 B7 x
    }' q( z& j& c5 Z# i  w; }/ b
    return 0;* i/ Z* r: g- A5 X( g+ A
}& U  r" g6 o0 i- m' X4 }* q1 v

) Z$ n: l+ M  y+ y/ I4 p6 C/ T( D$ N5 Z
然后编译执行就可以了(*^_^*)
9 i& D2 x9 K# I2 `其它:TC++上一定编译错误,不保证在VC6上也能通过编译2 D0 T5 l1 w  q1 E# _6 X
      建议使用VC7或VC更高版本,或者使用GNU C++编译




欢迎光临 捌玖网络工作室 (http://www.89w.org/) Powered by Discuz! 7.2