返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,1 w& }* [% K! U" J8 P! M" [
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
5 [- e# z' \& j0 d0 r& O2 Q4 E0 j只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
4 f; [* {+ A: s1 P参数解释:. f- x. S7 R3 n5 N- s+ l6 }1 u; |
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
1 v8 A" O8 J8 t& V# [& M2 x3 D/ fnReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
9 H' d0 K7 v! ^& B* ?% a返回值:4 }& c% z! w" ~( \0 x/ a" H% B
返回非0表示计算成功,0表示计算失败有错误: k% G7 G9 a) F9 U
: f3 r& E( Q0 }0 S6 V/ e
  x$ H8 e' s; ?% L; J! p* s

+ u; j$ k8 M  b程序代码: 3 L5 J$ n7 w6 f' p
/ _  a4 Q; }/ S" Q
namespace fy_Exp{6 L& l' ~2 `- Y& ?: H2 |8 M
namespace {template <class _T>
, }4 X- p8 ~; \+ d* t. z7 }1 ninline _T GetExpValue(_T t[], char& csym){
% W3 j- O* A7 J7 L* z/ i0 g7 I0 d    char c=csym; csym=0;4 i; m7 X# d/ ~
    switch(c){4 C1 k, ?4 L/ v( z) B7 f0 M7 V
    case '+':return t[0] += t[1];+ m' S& \7 v' N* }
    case '-':return t[0] -= t[1];
5 T, A5 i% j1 e& t: H+ D    case '*':return t[0] *= t[1];0 r: z/ k( ?  ?  p; N! _% |
    default: return t[0] /= t[1];//case '/':/ y5 L  P: i3 j
    }
$ t) ^% ]5 ?% x& ~" ^; ]}}
5 i9 y0 x5 T3 X' F7 d6 u, ]template <class _T, class _Tstream>; T1 z9 x; E1 T+ \# L$ l, i
/* _Tstream: inputstream, _T: get return value
* J6 n7 V" I3 Y2 Q; c! E* Return nonzero if get value successfully */) S( L6 i5 R6 X, o8 X
int GetExpValue(_Tstream& istrin, _T& nReturn){- Z' O7 \1 b7 K  b2 }6 U
    _T t[3] = {0}; //雨中飞燕之作1 ]! h( ]7 B$ G# M8 C) V7 `$ u7 C
    char csym[3] = "++";4 h+ R4 i8 X% n7 l3 P0 {
    int nLevel = 1, nERR = 0;
3 E1 n9 v* j. ?# Y. }& x    if(!(istrin>>t[1]))istrin.clear();
/ i9 h( f) _5 U! Q( v# Y1 ?6 [1 i    for(;;){
2 y' _( T; R' M+ i7 d  G" w5 t+ M        if(istrin>>csym[2]){3 U% A1 r6 o% S7 C
            switch(csym[2]){9 j  f+ M+ i) q* i& z
            case '(':
0 B  W" }5 O: w( j' W9 i- k                if(!csym[1]){nLevel=0x100; nERR=1;}else
. ^: y% F: E: h1 l                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;2 S) C8 w4 \# J0 @; H
                else{nLevel=0x100; nERR=1;}2 X- W. Z5 B& k$ O8 O9 o  I2 s4 N
                break;9 k' a6 t- P3 r# h( `* O
            case ')':
4 C- M6 |& }0 K' `/ k                {nLevel = 0x100;}break;
, J  [# h) C  X  e- v1 a5 P8 Q            case '+':case '-':case '*':case '/':6 L' p8 I1 s% u
                {csym[nLevel++] = csym[2];}break;
+ t0 |; d" L( x4 [; B            case ' ':case '\r':case '\n':case '\t':continue;1 {( k, ?; d' f  C
            default:
' E9 z8 Z6 |, F6 D5 U% H, M                {nLevel=0x100; nERR=1;}5 t% |9 I/ z( ^: Z# o( O
            }
1 e9 R. O& e+ \$ e# s            if(nLevel==0x100)break;2 [) U: y2 D+ C+ L& [/ D9 g
            if(nLevel&0x10 || istrin>>t[2]){5 P9 p7 ^/ x6 H7 _. M
                nLevel &= 0xF;' j+ f3 a) q9 g& B$ i
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}3 d! E( B- l4 W
                if(csym[1]=='*'||csym[1]=='/'){$ ~% u" P( C: t. P6 F7 f8 `
                    GetExpValue(t+1, csym[1]);- @, s# f: b$ |+ d* D* {  [6 W9 }" Q9 _
                }* ^4 x. p/ F6 H; s# m2 W; r
                else{
1 s7 y; R/ }! M( L# h4 X                    GetExpValue(t, csym[0]);
! }# y+ V9 I1 Z$ s' u                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;# Q3 j; S7 X4 b5 s% E' q! w$ L
                }
9 n9 g/ d" k' c$ Z                nLevel = 1;
/ Y/ {  Z$ J8 E+ x6 `            }
- H- E& b  |) r2 V' x2 {% Y            else istrin.clear();; ~) R( z( j7 q( |1 _
        }
- U3 }! V& e$ w" B        else{nERR = -1; break;}
! H9 l) K* R. E' }    }
  ^. B& A* `2 ^- i0 I0 A" O4 {7 h    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
, N0 r: W! m( X3 s- }) }  P    else nReturn=GetExpValue(t, csym[0]);
/ B1 W9 r) a6 G# U    return nERR==-1?1:0;
( @7 K* N- m8 U4 V1 B& y2 U/ O# O}}; y4 m) w1 \- s3 X1 ?) L1 w. P

+ z% j' q% r7 J& _- i: q1 L2 v# Q- X% X# g, A% R
6 F" s2 J* o6 I& O/ E. K! o
函数模板使用示例:6 p; t) J  F1 l% g3 _. _
在以上那段代码的后面加上以下代码:
6 F3 B( [0 s9 U/ S5 Z; w  }! O
* i7 t5 t4 I2 h& ~% Y+ ^, h
# X( x6 A2 I' m& d  S
- F1 s) f+ y8 h! }. `程序代码:
: V7 e; U0 y" n9 k' u- Y6 K
$ a) I( t1 w2 f) y; ?( z0 f* M#include<strstream>
5 P# g5 M7 p- U" @( L' l4 `0 Z#include<iostream>2 K2 N$ f) N* c; @! }, G( _
#include<string>
* z) x3 h5 ?& H: W# J2 Lusing namespace std;2 m/ R6 j0 a5 k: L9 _
int main(void)1 U- R  @' g$ p( `( u( `5 }6 |
{
8 o9 q# W' p$ {+ X    string s1;
6 Y& A% J/ ~$ @" M& ]) t    while(cin>>s1)
& p7 E& ?3 z: v7 K! {    {
) s; w( T& d& e& L. r7 V        istrstream isin(s1.data());
! p( |& C* S& ^: y/ r* g$ v2 `        double d;4 D; ~- F# t) S8 ]
        if(fy_Exp::GetExpValue(isin, d))" M2 a6 J% e# O6 W' I% `
        {
" A& v" O5 o- S. K            cout<<d<<endl;4 t& \, }; m) L! L; F" i0 _
        }
0 Y; f& J# h! t$ O% e! j3 E! r7 D( U        else. V: D& F- A+ D$ H+ P  Q
        {
, Y. [0 q  h+ o' R1 q& E+ I; D            cout<<"ERROR"<<endl;0 s* g8 G( y1 l" a' F( a3 [; E! H
        }
8 S1 Q3 C) t! Y2 Z    }7 ?# V* m, A, \9 F
    return 0;8 ^1 d9 v" Q. O; h, o
}
+ w" K' C* c" G" B7 c- i9 A% h/ n7 v4 f/ R1 J; a8 b

1 ~5 I# v8 O: L1 ^+ q1 p  Y6 D然后编译执行就可以了(*^_^*)  ~; O+ T/ g( ]. A/ N. w" I' B; A
其它:TC++上一定编译错误,不保证在VC6上也能通过编译1 L& x% q7 D( h" \/ \0 D- E
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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