Board logo

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

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

在9月8日那天我特意编写的,给大家分享的,
) X6 A$ q" r& A) D" W2 @; o- P一个很方便的函数模板,可以并且只可以计算含括号的四则表达式7 P- g5 X% N7 J4 f4 x
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
% G+ U. H  P1 O9 X  C参数解释:
  ], ^7 i; @5 U3 w5 U, }istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
- \3 A# g( q2 b9 h" p1 p  NnReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
% B8 C& Q1 ~9 J返回值:* v, Y9 N/ [1 L! ~
返回非0表示计算成功,0表示计算失败有错误) U% a" o3 A/ q- O8 Y

; i! i1 u' G* i" l6 o$ q " j! Y$ ~! m2 b) S0 K: z- p

% {( [  G. e; B+ H, l5 i程序代码:
: s* i, [6 ?! i. m0 z6 R8 W2 O$ c7 l8 S* D, ]
namespace fy_Exp{
( V" L! {/ v8 [0 I0 _* |; |namespace {template <class _T>& b- [) u# C8 \' K0 c+ z3 ~
inline _T GetExpValue(_T t[], char& csym){- K+ [* W% l# Z/ J$ X
    char c=csym; csym=0;
* p( `: [) P2 U* Z    switch(c){9 k! V# [/ Y9 ?; j% t
    case '+':return t[0] += t[1];% ~( W6 R! e& n% R7 f2 q3 s' K) z
    case '-':return t[0] -= t[1];
% l! a# z& V$ X  M    case '*':return t[0] *= t[1];
' s% c. y5 J2 j9 l4 o    default: return t[0] /= t[1];//case '/':
$ G+ f& J% F; k( F7 `+ F' a* b    }8 L* J) B2 p2 ?3 @8 _9 F. k
}}
" p$ r' h- @8 S1 p* f& [template <class _T, class _Tstream>( C$ ~  t% Y0 d2 g* g, B. M& }
/* _Tstream: inputstream, _T: get return value4 M  o- l: N4 E5 ]  ]# [
* Return nonzero if get value successfully */
+ Z$ _# V# K3 xint GetExpValue(_Tstream& istrin, _T& nReturn){
. e1 Y4 }, D! d    _T t[3] = {0}; //雨中飞燕之作+ r: ^5 F9 p9 N9 X& ]
    char csym[3] = "++";
  q; l& ~  m. P7 W& t1 y$ T    int nLevel = 1, nERR = 0;/ g# F. K( S* w7 E! i+ b; M
    if(!(istrin>>t[1]))istrin.clear();3 n. z* r+ U9 p1 v% ?9 ^; f& F5 y/ j
    for(;;){
/ A' r! Y9 _! A        if(istrin>>csym[2]){' |! x- N- \9 H2 X6 ]& c! ]' _- w
            switch(csym[2]){
3 D: v- b% x! o( e+ \7 [/ n            case '(':
: S3 T) ^+ Q6 |% m$ I# t  C                if(!csym[1]){nLevel=0x100; nERR=1;}else
3 q( D3 m: _7 \9 f+ g                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;" `/ Q  l, P7 C& T2 _# J9 z$ J
                else{nLevel=0x100; nERR=1;}& ~+ g( r& D2 ?
                break;, O* L: l5 L  R5 t
            case ')':* f, w7 V3 k1 W9 d( ^2 }
                {nLevel = 0x100;}break;9 s8 y2 [8 D* M0 \8 P. @
            case '+':case '-':case '*':case '/':! c- V1 i. I7 U  e, _
                {csym[nLevel++] = csym[2];}break;
) j/ `& A/ G5 S$ a3 m% o) k, [            case ' ':case '\r':case '\n':case '\t':continue;
( r& Y4 f% e$ c+ ]5 Y- d$ [            default:9 d) l. F* }3 Z* F2 v1 E. d
                {nLevel=0x100; nERR=1;}
' |/ d5 m1 v& l8 d) T' K3 E4 p            }
5 a' r& v8 n( l0 ]            if(nLevel==0x100)break;" g( e9 |& l% y% L
            if(nLevel&0x10 || istrin>>t[2]){
) `/ X% s5 q8 N                nLevel &= 0xF;6 p: x4 k2 K* ?) f+ }; V
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
) ?' b2 O, M$ B2 j. X+ N3 f$ Q                if(csym[1]=='*'||csym[1]=='/'){/ ~( n- d( e) _$ S7 h
                    GetExpValue(t+1, csym[1]);. S  k5 {  ~6 y( X+ ]
                }
) J6 i1 A+ Y7 o0 o! g  _# _! E                else{
  k% p. |6 e% _2 g& G9 ]                    GetExpValue(t, csym[0]);
  F1 g+ n. u! K, e) z4 L# j1 c3 k                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;) X8 h7 Z! x( R& p' d
                }
/ g  [# m- e- Q+ N3 e. ^                nLevel = 1;
2 s- D5 g+ d- Z, a8 }  a# Q1 x  ?            }* }  P/ f0 R, H
            else istrin.clear();9 ?- |8 N7 b: v" c! v# T; F3 }
        }
4 c$ e( Y- h7 q' }3 K6 M& `        else{nERR = -1; break;}2 o# G2 b& F1 N9 j8 t( }; L3 Z( e
    }
( @; m' K$ @. c2 G, w7 f8 m3 t    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
3 L$ Z/ Y7 Y8 U% ?( |    else nReturn=GetExpValue(t, csym[0]);
% n# e# s! x  i  ?. U- x    return nERR==-1?1:0;0 N. e* y# H7 R- \' @* e9 b  o
}}% \' L- e* ]2 |1 f4 I( R1 ]

3 h5 p* u( }( K& p4 `6 g( }8 H
# B7 |) R" i  [7 W
; t9 x" ^% N: ]: d# x3 c函数模板使用示例:9 ^. R6 ^. s0 w: `
在以上那段代码的后面加上以下代码:
2 F: E; F* D5 A$ g7 f- [1 ]8 J' \) F# E+ D7 r: V* i  M

$ _2 b  v) S7 |$ d* a' N: v  a3 Q! h, f# s3 M# C
程序代码:
) ]7 n  o' L$ I9 n0 V
4 V. q4 T" L2 M' v3 i3 L#include<strstream>& r, C- l4 u5 L6 g8 N. d5 H2 b
#include<iostream>
" _6 o, O8 X5 s5 H#include<string>: a% A; R# l* e, @
using namespace std;9 o6 I4 J$ a/ q# h! C( p7 J
int main(void)
2 r4 Q; ?  t& o3 K  |; v- E{! G2 k' X7 {5 s* P  A1 u
    string s1;8 g# Q$ B- F3 Q# x& \; e, O9 L
    while(cin>>s1)" F; S4 q& t* Z0 y
    {
: _5 u* I6 q& v7 F/ ?* G5 G% v& C8 M        istrstream isin(s1.data());) R6 v/ S+ ^: @% \6 K; e' c
        double d;# e# o2 a3 w0 J; Q# B# Y8 C
        if(fy_Exp::GetExpValue(isin, d))5 ^( U: F; k" A3 E( p2 Z+ a' J
        {! R* {$ K$ G; [1 P/ n
            cout<<d<<endl;, D  n+ Q7 g$ w9 b
        }# C6 }  Y- ]+ s" D$ H. G
        else
( @1 a, t: W+ P* l% n+ u        {
* B; s9 I  H  g  R            cout<<"ERROR"<<endl;
" o0 U1 o+ @- E4 z        }
& C! ~" t8 n9 R6 _    }
6 E5 Y! }- ?( b3 q) a4 R% g    return 0;/ D8 M" B! m' M
}
' d0 _" x  U- V
& I5 h- {% \4 V7 C
" a0 q. j1 u1 v& ^9 O3 U4 A然后编译执行就可以了(*^_^*)* ]/ b+ ~- q. X2 q6 A
其它:TC++上一定编译错误,不保证在VC6上也能通过编译
6 r0 B% x! f7 M! R" A6 W, E% m; q      建议使用VC7或VC更高版本,或者使用GNU C++编译




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