返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
  V/ U8 _, `- i9 a' \1 V  i一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
6 `  f" Q  o' L4 k0 @: V8 a只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
+ ~7 H7 H$ `) ?) }; y, ^参数解释:
5 m) _$ J1 _2 X/ p' c4 nistrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
! u  o' Z9 }. M9 J* Z! x# tnReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
% D0 R9 ?- Q9 E返回值:
1 g! ~- X2 G% |4 L- [& |返回非0表示计算成功,0表示计算失败有错误
, x( K8 z8 d; _* ~! s. Y# P* \7 _) `7 K# t( k
' `6 A* q8 [5 K4 w# l0 F
) T6 H3 k! K) S! M/ g/ _  S. t" v
程序代码: ; r) S) B' H: T7 f6 F4 S0 ^5 m; t* z

3 E* S+ i* J0 R6 snamespace fy_Exp{7 p! t$ c8 w& p/ c
namespace {template <class _T>
0 y* l% C3 G" S& l  Y* r2 d' h' \1 ^inline _T GetExpValue(_T t[], char& csym){3 ~& j! ^" Z6 X3 ~6 t, a7 ?
    char c=csym; csym=0;+ ~* B9 E: L, n' ^: t1 ?
    switch(c){$ R, K  U& S1 @* Q# p2 X
    case '+':return t[0] += t[1];$ w+ X+ K0 m# b2 _* U6 |: l7 n
    case '-':return t[0] -= t[1];
& z+ P* U* z! z5 y' K4 a8 V    case '*':return t[0] *= t[1];6 l  Y9 j! M1 M6 S) ?) E
    default: return t[0] /= t[1];//case '/':6 p. |1 h( v8 n
    }0 B# K  v$ B5 u
}}" M, l) H( g) F/ H; \
template <class _T, class _Tstream>
6 O5 f6 s6 _$ f5 C( Y1 {. C/* _Tstream: inputstream, _T: get return value
4 A; r3 g4 A  {) S( _6 ^* Return nonzero if get value successfully */
0 E: [2 w( m4 d' P2 V" k' aint GetExpValue(_Tstream& istrin, _T& nReturn){7 f) Y* Y  z4 @! N5 k
    _T t[3] = {0}; //雨中飞燕之作6 Z+ m1 w& g6 `5 F% Y$ B
    char csym[3] = "++";
& h# E. \: \+ R% g# y% q, _    int nLevel = 1, nERR = 0;
1 O# b7 d2 b; L) Y# ]3 X    if(!(istrin>>t[1]))istrin.clear();9 o/ V, O; B$ O* h6 Z4 t
    for(;;){
6 X. @4 R1 K" o1 B& B- i/ K. E9 I9 B        if(istrin>>csym[2]){$ R' O0 S$ Z# Q! n7 ]1 j
            switch(csym[2]){
5 n7 h3 U; w: |  k# y            case '(':5 v7 ^) X% `6 I1 p& }, X
                if(!csym[1]){nLevel=0x100; nERR=1;}else- s1 t  g5 |6 H
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
1 K5 `% |- ~8 Q1 G% G  y2 s- n. `, [                else{nLevel=0x100; nERR=1;}- J9 F% D3 m( |7 S
                break;( z- F/ V' \) t- C* h6 H7 l1 ]
            case ')':
1 S& e2 M* u! Q' @+ R+ E                {nLevel = 0x100;}break;/ Q: F3 G# W1 V' J
            case '+':case '-':case '*':case '/':
. I0 j0 o9 A4 L                {csym[nLevel++] = csym[2];}break;
7 P$ o6 S6 t; _) p2 l            case ' ':case '\r':case '\n':case '\t':continue;3 R% Z! y, L; y( x6 ?* \( `5 M
            default:$ h) t1 D* E- t$ N8 F
                {nLevel=0x100; nERR=1;}
8 ]- x9 j- i4 I" c3 a            }
/ g  t) U/ j# O' n7 ^4 S            if(nLevel==0x100)break;* z2 P2 {! T7 R" A  b! ^# _
            if(nLevel&0x10 || istrin>>t[2]){: r7 d0 G# S0 u0 I3 J. x; `( G
                nLevel &= 0xF;
) _  Z  E- M) S# c0 `2 n                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
: _+ D8 g$ U4 h                if(csym[1]=='*'||csym[1]=='/'){1 L% n* p" E1 @- P5 w
                    GetExpValue(t+1, csym[1]);
- O( @4 F9 n, c: i                }
- k8 z+ P0 Q: F9 Y4 ?1 _% Q2 |, M                else{  h! b9 J$ @2 S; u( _7 G
                    GetExpValue(t, csym[0]);3 v5 Y6 }+ W8 Z+ k% }+ ?% u, {! I6 C
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;% d4 ]" |- x& ^& g! U! Q
                }  o; r0 e* m4 u, p. N
                nLevel = 1;9 b- `+ ]6 x+ N4 V; O& y
            }. L- U" [( G, I) i
            else istrin.clear();
9 v- {. _, O, C' T% }0 f" l) b        }: |  o* R( q- E
        else{nERR = -1; break;}
7 V7 p# l9 z& k8 n, }  V# B2 t2 G6 ^' `8 ~    }
+ ~0 _/ h$ t* i& H+ O$ j    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);- V) J( R, B5 P! |( \1 U! r* u
    else nReturn=GetExpValue(t, csym[0]);2 y+ O; w5 |) s, @# I8 W+ u
    return nERR==-1?1:0;' h; v* X1 W7 a
}}: L7 x2 |+ o5 I

0 k6 I3 Z  Y7 _9 ?1 S) I4 X' ^$ q4 f. |; o1 t4 j: g3 J1 R
7 Q. N+ z: W/ E. I( W/ u+ h
函数模板使用示例:5 I. M( \- C  [: A
在以上那段代码的后面加上以下代码:5 y4 P' X& c# ?! l) s" }
, |% P6 e4 e; s( b

2 H5 Y# K. b* u
. [- p0 s1 }4 S- o+ W& Q+ _1 b& U程序代码: * t  d  O8 e1 a0 @: ?

' X$ R/ I' v& D; n#include<strstream>
+ p1 f  I, y# Q# L- w4 X#include<iostream>) n" U  w9 b8 O7 ~. G$ b: ?
#include<string>
4 h5 }' j5 D1 o5 S% W7 T5 \' A9 E4 x( iusing namespace std;) Z9 M( y2 B0 b+ c/ P
int main(void)( T' F: L5 j+ r: ?6 k, ^" |1 W
{
! R, F+ Q, P) p8 E" z, z    string s1;) ]% t- C- f( g- ~7 A8 T
    while(cin>>s1)
% B$ V" [3 l. s" A5 L* y- n' K- r    {. i# Y3 z5 y4 T, k/ J- K1 \! ^; Y
        istrstream isin(s1.data());  B. t; @1 {, m$ h9 o$ o& h
        double d;
) [# K6 d: J) e2 G        if(fy_Exp::GetExpValue(isin, d))5 j% Y0 V2 k" ~) `
        {
" Y+ F& P0 J* T6 K0 C* }            cout<<d<<endl;+ d# d" ~8 T! }3 X  N
        }
7 c# g7 I' X0 K( d  P8 r        else# Y, Y  J' w9 \) P( d' o3 \5 L! e
        {
7 n* F' I) j. O. e            cout<<"ERROR"<<endl;% y. y5 E: H$ R, L" `/ F% V
        }1 r  P3 j. P. {  U5 S  r* G
    }
* X+ L8 `- i1 l: q" H  E/ A    return 0;8 H: `1 U# J# w0 z! y/ @
}2 [. R$ P) V; o
5 L, r0 J* ~! ~7 H

6 u. M; P, K$ J7 I, {然后编译执行就可以了(*^_^*)
6 s9 T0 c( l5 m其它:TC++上一定编译错误,不保证在VC6上也能通过编译
5 N3 I8 I" ?& t  A      建议使用VC7或VC更高版本,或者使用GNU C++编译

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