返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
/ x, D4 v/ ~1 b- Q一个很方便的函数模板,可以并且只可以计算含括号的四则表达式) d. p+ j7 _4 _( o3 c$ N
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
8 l( w' K) r4 ]1 H& w. t  ^: Q参数解释:
. I6 b" t, G$ Ristrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流; ?. D$ J0 `2 c* [
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定% y7 a9 e0 p) {
返回值:
& j( `1 b; }5 n! ?1 S5 G返回非0表示计算成功,0表示计算失败有错误2 i/ `4 G* k5 w  D" V6 `' s1 S3 Z

6 @: j4 Q9 \) O& R0 W1 E3 w, w( S# ~$ ~ 9 s! k; A" H1 p0 V
% H$ Q* d( U5 I6 T+ {8 q
程序代码:
& _& T2 o! Q! m
# w& y! X. n  h% l9 E( s( Gnamespace fy_Exp{+ I6 f, h" u: I" r' `
namespace {template <class _T>
" o: |2 }) [0 Rinline _T GetExpValue(_T t[], char& csym){
1 {& ~, {! n# _7 U0 |- q5 m    char c=csym; csym=0;; W0 [, ^5 f7 b! U! g
    switch(c){
# ~+ H' B6 ?/ q( s" [+ O; u$ o, `    case '+':return t[0] += t[1];
8 x& x4 s5 |* V. r    case '-':return t[0] -= t[1];
( y; F$ c$ K: b/ L5 d# W# N0 S. u    case '*':return t[0] *= t[1];2 n6 C, M! X+ ^, C  Q( t* }- `
    default: return t[0] /= t[1];//case '/':* y8 v( b0 e# q1 \
    }" M. e. a: O: ]: S7 O- |
}}/ n/ i# x6 F8 L% D% r5 M
template <class _T, class _Tstream>6 q; u% o& \" S! z1 e
/* _Tstream: inputstream, _T: get return value5 z8 P3 [  E$ R# v7 m- z' d* D
* Return nonzero if get value successfully */9 S0 o. b  f- Y1 L
int GetExpValue(_Tstream& istrin, _T& nReturn){
* J# n! L, N' g' I- [- \5 d; D    _T t[3] = {0}; //雨中飞燕之作  M. R' S. T$ _6 A  |$ ~7 A
    char csym[3] = "++";
0 o& i& u6 a5 v. C( b    int nLevel = 1, nERR = 0;
) L* x1 u& p0 y1 |6 ~8 x    if(!(istrin>>t[1]))istrin.clear();5 K; o; u2 u1 r5 O
    for(;;){
' f% Q. a5 }. `) Y4 e! [# Y- f0 f2 ]5 Z        if(istrin>>csym[2]){
3 x4 e4 p  [  G' A" r, ]            switch(csym[2]){, e; I6 H8 I) j  _
            case '(':' W8 J& {# J/ X; H
                if(!csym[1]){nLevel=0x100; nERR=1;}else8 L2 W4 s# Q. J9 D* y! j
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;: Z* c2 n3 O$ G. _
                else{nLevel=0x100; nERR=1;}$ s9 I1 `4 ?  h( ^" Z
                break;0 N+ U, }" T2 L; z# b* G2 q! H
            case ')':( m' q1 W; r$ A  |9 ~6 y) Q& R) h4 M
                {nLevel = 0x100;}break;+ N6 l- g# d( |
            case '+':case '-':case '*':case '/':( E' O8 r& Z+ X9 h0 e% U
                {csym[nLevel++] = csym[2];}break;
( h  C, F; |. G4 z2 D            case ' ':case '\r':case '\n':case '\t':continue;6 t  T; c( f7 w6 h; |
            default:# R/ I' M. U# k% r  A
                {nLevel=0x100; nERR=1;}9 Q) M/ c+ r' v# j. Z7 c8 ?
            }
( ]2 k$ r" D( w5 Y) U0 f- M            if(nLevel==0x100)break;! e$ r: b5 z* e. l7 w6 e
            if(nLevel&0x10 || istrin>>t[2]){
* Y  S6 I- B5 |1 a2 j. q                nLevel &= 0xF;. u, S) B; }) `; t8 r
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
3 v4 l- T* R- Q! J( ?                if(csym[1]=='*'||csym[1]=='/'){: p/ E2 {8 ~+ ]% I4 C& [  M
                    GetExpValue(t+1, csym[1]);
) r" a3 `% R, p                }- {" O7 m# t. T5 b8 J& _8 ?
                else{
/ o( f3 N0 k* a( g! Q                    GetExpValue(t, csym[0]);
" N* u# w% k4 m( @9 i* i                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
9 d- E. }. W$ S' |- h0 G5 G                }( O% @8 Y$ Q" @" s3 T  Q, |2 t. f
                nLevel = 1;/ e/ p1 O1 l, v3 ~8 j; J. i
            }8 S  J: Z! k/ M2 k! d) [2 ~
            else istrin.clear();
- e2 Y( F2 J. Y* m- H' c        }( l) p4 h: D+ r" c" ]/ ~6 F
        else{nERR = -1; break;}
# ?6 Q7 u2 H  |; l6 l4 [    }
: E/ `" _' ~! S* G! g    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
1 H7 E, i, k- x% x  ^    else nReturn=GetExpValue(t, csym[0]);
9 z8 S  L/ }! U9 `0 n' t    return nERR==-1?1:0;7 w& A4 q$ [' t; [# _
}}
1 ~1 ~1 ?2 d& ?; E+ S3 J5 U, z0 m0 a1 ^2 e2 M  E
4 e7 o3 o* E2 ^0 j- n  C

% E/ d1 G) W- i3 ~$ W( s函数模板使用示例:
" P- W, U6 \" N7 a在以上那段代码的后面加上以下代码:
; r2 U# ]3 b% |
. f0 U1 R# {( W* ? 5 u* g. O. o& g3 G3 [: i/ x

3 Z0 k' n* ?/ `  X# \& N程序代码: 4 w6 X. J, P, g, J; \

0 Q* r0 i+ p& o! Z#include<strstream>; R  M# @: `7 Q5 [7 \: i( I
#include<iostream>
- H" R% v8 o- m' ?5 F0 n#include<string>
1 Z# g+ d: [2 X0 k. N: Eusing namespace std;+ t. _6 z! i' c# O$ o) V! i
int main(void)( y2 |6 q* O4 l. I7 k5 O
{& T  _! p& F& a* w6 V, V3 n
    string s1;
% ?$ ^2 H. r+ r+ q( ?    while(cin>>s1)
. I5 _6 i5 R% R6 F( T$ m- X    {) y0 e5 ]5 J2 a$ V  E* M/ P' L
        istrstream isin(s1.data());
" z& e' q6 O: K- E, \/ C        double d;
2 ~; |# Y3 ~! b4 M2 _! C8 L' ~        if(fy_Exp::GetExpValue(isin, d))' f5 O) C0 A7 z- d1 F; k
        {; B6 a5 m0 p. W# b9 }3 I% f: A; [
            cout<<d<<endl;
7 F& M7 R/ O: A3 K3 e, i        }
" j2 _3 t! s* ?2 g2 w        else2 A/ @. s+ m5 |; H
        {/ _# N8 C0 F8 {0 p  f  z
            cout<<"ERROR"<<endl;
% J0 d! X- E7 q- [* U& k        }
- f' F& `, _/ P    }3 s0 Y4 n' i; D/ j9 D" J% ~( n
    return 0;0 K5 i- U; }" c. E' ]: w
}3 a6 K3 W# w( o* X* t
/ u, c; }- X4 r0 `" N% r1 Q4 M

+ E3 r* a4 @% t; U- r; E" |然后编译执行就可以了(*^_^*)
; e% ]0 N1 D( J% S, H0 }4 [其它:TC++上一定编译错误,不保证在VC6上也能通过编译8 Z" P" J7 W2 B6 a* J/ G
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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