返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
! V4 {# K/ R5 v9 J, ?一个很方便的函数模板,可以并且只可以计算含括号的四则表达式/ o' S, [$ T% Y$ L5 u
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
- T% E; L. z% M$ Q参数解释:. f9 L" y* A! F$ b) m  E  ^' e
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
' S' @9 Y' z# N$ G/ O1 ], @nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定# w5 b! _# ~) {5 m3 L2 ?
返回值:. G: W# K; u8 k
返回非0表示计算成功,0表示计算失败有错误& n5 P# G6 G' i3 H9 u% a/ L
4 d5 A3 \$ ^: d* e9 V# U; ]9 G

* R- L- ~6 d5 K# `1 n9 ?  ]+ {3 D% {+ v6 ]
程序代码:
) ~: c: E# g- [6 X
+ _( P6 Q4 H' B5 j% v: L: u' rnamespace fy_Exp{) M5 s( B8 {/ @8 p' t# D' b- R( i
namespace {template <class _T>
2 Y9 n+ c1 X" `; y4 e6 vinline _T GetExpValue(_T t[], char& csym){
$ q2 Z: v4 t2 a% j, }2 c3 ^    char c=csym; csym=0;
8 ], g, ]) t) _$ S. m- x, }    switch(c){
! }: [4 ]2 h! ~" S3 R4 ?    case '+':return t[0] += t[1];% M; H) `. [/ H+ B% q
    case '-':return t[0] -= t[1];1 B; B: O$ }: `5 }9 s+ G' z9 a
    case '*':return t[0] *= t[1];6 T. ^4 ^/ [7 v7 k" ]/ R5 q9 n+ |# x
    default: return t[0] /= t[1];//case '/':6 A" D0 l6 v% {& m, \6 M$ g
    }
! e. G& c- b  K2 Q8 L1 b1 {7 x6 s# G/ ~}}
& M1 Q( V% c: H3 A, stemplate <class _T, class _Tstream>
% _* I' p) b  D' T. L, m4 Z/* _Tstream: inputstream, _T: get return value
0 x& o  u0 ?9 D1 |3 b* Return nonzero if get value successfully */& X/ b. h& j% R$ F& [
int GetExpValue(_Tstream& istrin, _T& nReturn){
& K+ k1 U! V" s- S( O" p4 p    _T t[3] = {0}; //雨中飞燕之作, }) p# A$ a, {
    char csym[3] = "++";; G8 d$ x4 C9 Z; G
    int nLevel = 1, nERR = 0;  H8 Z6 O5 |# `# w% A7 H
    if(!(istrin>>t[1]))istrin.clear();
1 p. o9 Z; E( J5 N. {- j( c7 u    for(;;){
# t. G" o5 Z2 L/ Y# N; R( U        if(istrin>>csym[2]){
" ?+ V3 ]) D6 ^7 x+ m  N            switch(csym[2]){
5 ]/ B5 u$ Z" T' b* Y, S            case '(':
% A" d. l. W5 p0 }1 R                if(!csym[1]){nLevel=0x100; nERR=1;}else4 w4 B* P) o1 Q& n
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;& S$ y/ G4 \4 M0 v, w
                else{nLevel=0x100; nERR=1;}. @6 a2 ~6 O  D1 W) ^) u" O+ w' W1 o  \
                break;
7 T% e# x- P% L: J' X            case ')':
" Z) J( i3 L* j$ m                {nLevel = 0x100;}break;# I; E0 A! W1 a/ i4 \& {
            case '+':case '-':case '*':case '/':
- c& f5 I, Z/ ]8 p                {csym[nLevel++] = csym[2];}break;
9 j5 C( D. D. F0 e; A            case ' ':case '\r':case '\n':case '\t':continue;
' i6 f& s3 S: y# G( H; h            default:1 c6 P; q, Y/ U& p
                {nLevel=0x100; nERR=1;}1 q( M6 W5 O9 z- Q. Q5 `
            }( C7 }; K7 c8 M4 B' p% T7 |- g3 _
            if(nLevel==0x100)break;
# U& m1 Q! ~4 x" \            if(nLevel&0x10 || istrin>>t[2]){
0 u& r( W" [* h                nLevel &= 0xF;" g9 e6 B! t9 r. l6 C
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}0 a0 ~3 }! _' o+ r/ ^- o4 H
                if(csym[1]=='*'||csym[1]=='/'){
$ _1 b* V: q: Y1 a& ?, O                    GetExpValue(t+1, csym[1]);  k  W) g/ ?9 d! T. x+ k- x
                }7 n" [5 j+ A9 K0 h# ~
                else{' J: |! T2 p1 o9 V8 v+ N4 _
                    GetExpValue(t, csym[0]);
/ K) a( K* ]: m0 ?5 ~                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
: ^, E. c5 I* C8 t4 J2 F  Y                }/ l1 |" ~& L6 u  D
                nLevel = 1;6 W4 u$ ]* C( i/ m% r% {
            }. T/ w+ U0 x' g
            else istrin.clear();
7 U' o% b: P3 _( Y) v3 I% y( B        }8 {5 A( I9 Y& S0 P3 D) G" r( p, r/ `' l
        else{nERR = -1; break;}
4 m1 w2 J( ^9 N0 ]9 r# e; c" C    }
6 p: a" B! u1 F1 u" i    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);  s* {8 S$ g; k  s% N8 M2 A# H1 x
    else nReturn=GetExpValue(t, csym[0]);( u/ V" N& ?: f; Z9 {* T$ I* _
    return nERR==-1?1:0;
/ |8 h: u$ Y9 g+ {* w0 T4 I}}
7 T( I: F$ T0 X- g& ]2 x$ b7 L
: _+ w: Y% c4 |3 W2 z/ C4 }2 ~) a% ~9 R# {/ X/ N

9 x/ o% z  i$ x' a函数模板使用示例:
( a9 C# |2 G! F4 Y/ L在以上那段代码的后面加上以下代码:$ g4 R4 j( z( b. R2 [
5 I( G% x) y  a8 a+ f3 X

& B  e: D- m3 W. t$ G+ `7 q' [! s% j  k2 J8 m2 ]
程序代码:
+ D3 L) j* m3 s% k, G; `/ }0 A; k$ h. R  a
#include<strstream>6 `) c5 ?+ ], g
#include<iostream>
  U+ X! d! E: }7 O- z#include<string>
! X# e2 Y& b7 t$ S0 ]# q7 H) yusing namespace std;
0 ~0 g9 ~8 n* O! U' [8 e* Oint main(void)9 w) A9 Q. q6 D$ G" N' O& }# S0 |
{) R% r" J  s5 D; w
    string s1;  u/ C7 M) O% {6 P! f+ N, q
    while(cin>>s1)
$ N$ w4 I" Z* a# W# [) P8 P% G0 @  E    {1 z* C- }! H( P% X- j
        istrstream isin(s1.data());' U0 M( v" w; y& A
        double d;
+ x% ^7 ^2 s& u        if(fy_Exp::GetExpValue(isin, d))
: E2 X" |; K; K, [% u( ^        {
1 t# k3 Z0 }# F5 y% @, N            cout<<d<<endl;
! B2 t! N" Z( r  I9 o. ~' z        }
& J+ O- U" p- F/ u( d0 ~8 t& I! j. L        else9 }: J& ~+ [( m. c. o2 ~) R; ~
        {0 ?) W9 _+ W; W1 H
            cout<<"ERROR"<<endl;& `( i; K, L3 h3 r2 F- w+ z+ @
        }; [4 G1 i. ~: U0 C7 j& _7 z
    }
4 K2 ]# G; e. O4 a6 ~. k7 Q& r    return 0;+ M+ E& d- x9 A1 f- x' ]5 Z* q+ |
}
4 K1 ?6 o, Q( k( H- Y  V: a* O/ j" ^: S/ K

# q. l5 z& d7 J( u6 `1 R( t/ l- u- o3 \然后编译执行就可以了(*^_^*)6 Z0 v+ s+ L+ b. N6 r
其它:TC++上一定编译错误,不保证在VC6上也能通过编译$ i, d6 y3 X5 W8 R) `, J
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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