返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
* I2 `1 B$ q6 H+ d( ?" r& u5 Y一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
' ?. U& F% j( J. Y+ ?! y只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)! [# m& k2 b" U2 |% u% H; ^
参数解释:! _9 C* z9 L5 P, R1 i
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
! G* Z' }+ h" Q: Q' ~" D# TnReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定1 B! o, S. B! V0 p* D: x
返回值:. f* d% t1 F1 o3 c& \- |
返回非0表示计算成功,0表示计算失败有错误
1 ?9 |+ v% @4 i2 b8 [. C0 U9 T/ {3 R1 T5 l' e# a( r" f$ n

( Q& ]1 u$ p* X/ _' C  P0 `5 R# y) E/ Q; H' f
程序代码: ) A' G( ]: ]7 z- _5 C: w1 o5 J

8 ?+ G0 v" I3 M4 N- l9 u4 pnamespace fy_Exp{
" f* T: X5 K& c8 e; vnamespace {template <class _T>+ P& S+ N( M1 a" q! r+ P9 r5 z
inline _T GetExpValue(_T t[], char& csym){
2 m& A& L* L# F% \# @    char c=csym; csym=0;% M7 t9 D7 }) ?1 ]! F
    switch(c){
1 J$ a5 e* B! s& |8 X- O% {    case '+':return t[0] += t[1];
; y1 M2 K% ^( X7 m2 W7 ^    case '-':return t[0] -= t[1];
. F2 H2 E6 m+ @- x! q2 O! W    case '*':return t[0] *= t[1];
* I( V0 P" C) c5 J7 I# t    default: return t[0] /= t[1];//case '/':  z- \3 }1 G, H; z& @- [$ w* x* ~
    }
; G' h' q: ]2 Q, Z/ ?6 p}}! p/ N8 i9 X1 X$ U! B4 v- W
template <class _T, class _Tstream>/ ~% |) x; I/ d
/* _Tstream: inputstream, _T: get return value( x2 f  u% [' N3 P! c
* Return nonzero if get value successfully */! z5 a0 \2 g8 z, u9 c9 D; W
int GetExpValue(_Tstream& istrin, _T& nReturn){
5 ?9 U6 u* d8 g. x$ V    _T t[3] = {0}; //雨中飞燕之作
% K" i; \8 D/ v* Q    char csym[3] = "++";$ j9 y5 M6 S) k$ S
    int nLevel = 1, nERR = 0;
5 j; ]* d5 G# W4 B# |" r    if(!(istrin>>t[1]))istrin.clear();3 c; j5 a* C# e3 D& H9 u7 D
    for(;;){* n( Q; ?8 H! X
        if(istrin>>csym[2]){
9 e) d  F6 V9 Q2 _+ s$ M/ T' H: ^1 u            switch(csym[2]){
9 h& w  D; M: G- G/ w" {+ b4 W            case '(':
8 }. z" I4 B2 [+ t3 F( G                if(!csym[1]){nLevel=0x100; nERR=1;}else
" Y' W3 W( X& p- ?1 b8 L                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;+ D% s- Y& v8 O/ D% _
                else{nLevel=0x100; nERR=1;}3 j# {4 @+ P0 F; K
                break;5 z% o. p9 b1 ?0 O
            case ')':
# R0 b* m8 [6 o6 H                {nLevel = 0x100;}break;- [/ g& _, I# N. M2 |( o  t
            case '+':case '-':case '*':case '/':
% e: t3 {" q* n& q" c# C3 }0 I                {csym[nLevel++] = csym[2];}break;
: m6 \8 K# Z- Z8 X: J: Y0 {2 W5 [) R            case ' ':case '\r':case '\n':case '\t':continue;6 j# t0 G7 F. U7 S; U
            default:
$ f- c( J" V- _' ]) F, h; S                {nLevel=0x100; nERR=1;}% S) ^/ u6 N/ I4 h4 i% p! O$ y9 U
            }1 g) S1 y# y4 E" ^
            if(nLevel==0x100)break;/ W, w6 P4 r2 t$ n: ?* h4 {% W
            if(nLevel&0x10 || istrin>>t[2]){" }6 t8 p2 _) _" Q1 N1 b" {* [
                nLevel &= 0xF;
1 _) h/ y& d0 }- g2 p/ Z( r' F6 O                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}6 k0 ?- j4 U0 h) \
                if(csym[1]=='*'||csym[1]=='/'){4 p$ F1 f' U6 e
                    GetExpValue(t+1, csym[1]);
  E& Z0 p1 r$ Q5 Q& @6 T! d                }
4 D# F: n+ t. W& O& `& o5 C                else{
" o4 E8 `3 j/ Z. P6 u& P; j                    GetExpValue(t, csym[0]);
) f3 P/ {+ K. R" U6 T% Z                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;. P+ Q9 Y7 j  Z) b* }8 A
                }
* F1 ]& f8 d; ?/ G9 a7 _                nLevel = 1;% {; R/ ]  F" Q! u2 [! ?7 [
            }
+ G( i4 h, ]. I; z- v            else istrin.clear();7 b# r: \  k" k& _% J* s. x
        }
8 G" ^% u/ e" K6 |9 v        else{nERR = -1; break;}
/ P9 j/ l0 E" I6 q    }
3 R2 `6 j2 l. Q' J3 M" B2 }    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);$ V. O# H& j, x! A# b0 T
    else nReturn=GetExpValue(t, csym[0]);
/ J$ z1 ]+ t% v% c3 A$ a) N    return nERR==-1?1:0;" h5 x8 y4 Z0 X& ?- U
}}
( N8 N+ e* D# E) b8 I+ _  v4 y! \+ L: d
$ a9 `0 m* f3 z7 p& R3 c( D- S

5 a+ `9 {/ G( m3 c) g& v0 \% G函数模板使用示例:
$ o1 W7 z6 \' a7 L( r在以上那段代码的后面加上以下代码:: A: |2 a# F! _( X2 h5 _8 g
( m& d  l3 M, D  l) G. C

1 [6 S3 Z. r6 i* Q
7 i+ _( d9 W: H: }$ |" ]- [程序代码:
/ x) d4 i) |" ?# {1 x" q0 b2 L: r4 k( |6 j
#include<strstream>
7 o; X/ u+ a$ C2 }" B* v6 r#include<iostream>1 t. r2 l1 x# E, B' G
#include<string>
* K4 F" v/ y9 `, lusing namespace std;
4 E4 ~) e7 E+ U5 l- Nint main(void)( j$ z0 f4 }; }" r! a7 t' m
{
$ O* p# M! z( Z- p+ @  `- J" n/ x    string s1;
. p2 W( B6 R6 ?' a( Q    while(cin>>s1)
( z& A2 h; F8 j/ h* }    {
1 E  V5 t' X! p$ z% Q        istrstream isin(s1.data());/ {% {/ f8 L1 D" C! J8 f2 J% J
        double d;
, x/ I+ c) b, z3 h( K! R        if(fy_Exp::GetExpValue(isin, d))
" R% }% b) R+ C  Z" @1 l        {8 h: I3 i$ L- X8 A
            cout<<d<<endl;
. p4 f5 t" _+ h# p  P        }- n' s9 J8 e( h
        else7 w; }- o8 K# @% w3 X4 j
        {+ @4 ~* F  z% h9 y
            cout<<"ERROR"<<endl;
9 z; o3 h9 p+ a        }  w  L' o7 j( T9 F6 l
    }" j3 a3 t& i5 r) d
    return 0;5 u( G- G/ Y3 `+ Z  m
}9 c, v  a4 s  M1 H
" [( c3 N8 t1 E! C; Z
# p' `2 v, F5 p$ o1 E% E' `
然后编译执行就可以了(*^_^*)
5 T5 Z2 t; t1 c% p! _6 t% [其它:TC++上一定编译错误,不保证在VC6上也能通过编译
$ t) E# O& W: c  d, I+ J# \* ]      建议使用VC7或VC更高版本,或者使用GNU C++编译

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