返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,. a" J$ m3 X2 f& @9 n8 `8 w0 G# r4 q
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式+ y5 O% _4 I) b; a
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)# `- \/ \. k( s: Q& S
参数解释:& D2 U* _& `8 B& v+ \! X. ?7 Q; i! ]
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
2 l8 K5 s" M- @$ ?2 S9 R4 j( }nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
4 [; ]! l; T; R, _返回值:2 O0 m* Q* p1 R2 a5 C  [
返回非0表示计算成功,0表示计算失败有错误
; |  i' h* c% H. L  \" w9 {; k
1 ]. p: ^  m8 l) e' W0 i0 |$ d8 ]- Z4 } 4 m$ X3 ]0 L4 z( v0 k1 l
/ r  C: V  R) f+ L7 j& J) S  }
程序代码: ' T7 j0 G$ E5 Y. I+ `" l# B
7 q3 x2 N9 Q* Z) B
namespace fy_Exp{% w- L. [0 n$ q0 a0 J# ]0 @: e( P
namespace {template <class _T>! y' m5 V, H( A
inline _T GetExpValue(_T t[], char& csym){
/ d0 M5 t, {  P' L1 I% a' J, _    char c=csym; csym=0;
3 b" B# d- p1 }& }: `9 ~    switch(c){9 G6 w' K. j) Q
    case '+':return t[0] += t[1];# Y- t, G& `4 k) P7 F: o
    case '-':return t[0] -= t[1];. Z' L7 t( y; @! D
    case '*':return t[0] *= t[1];  U0 i- ~6 T. I
    default: return t[0] /= t[1];//case '/':5 O0 p2 G  n' d
    }
( X5 D: u: m# P& }}}
+ A3 u" s7 o# P9 ]  ktemplate <class _T, class _Tstream>- |6 D7 s5 L( J9 h$ g) v4 M1 {
/* _Tstream: inputstream, _T: get return value
) o5 U) K2 ?; L( m# y5 b4 @5 E7 @4 Y* Return nonzero if get value successfully */
# i# x0 Y& A! z- fint GetExpValue(_Tstream& istrin, _T& nReturn){
: l! B! i& V* t  R8 j4 y1 p; R$ }    _T t[3] = {0}; //雨中飞燕之作
& m" z( s' C5 X6 f    char csym[3] = "++";
- Y4 T0 }/ I4 l5 T4 N    int nLevel = 1, nERR = 0;
, S' n0 O9 y3 O, q6 ^    if(!(istrin>>t[1]))istrin.clear();( m  l" ?/ G) L$ r" d
    for(;;){  o4 ?1 k+ I7 j0 C
        if(istrin>>csym[2]){
9 t5 X* {# U4 N. K/ Y" e. D            switch(csym[2]){
1 V0 s- Y" c( I! B7 ?; G- u            case '(':
, d: i0 q! o# W                if(!csym[1]){nLevel=0x100; nERR=1;}else. Q- N" M( g1 c% P; @( q% o. y! M
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;4 f' c3 V/ k! l9 T
                else{nLevel=0x100; nERR=1;}
; l2 q  E' n) {4 m& \0 W# k                break;2 R7 v5 E- e+ J* U
            case ')':
1 N( G2 `* f0 Y  D                {nLevel = 0x100;}break;
- f1 n# S( p3 {* Y4 q            case '+':case '-':case '*':case '/':( l) t) h1 c! F$ T8 Y! `
                {csym[nLevel++] = csym[2];}break;9 R0 V6 d! M' f: F4 |" e, s  |
            case ' ':case '\r':case '\n':case '\t':continue;  x* r) M7 G; a% ]( Y
            default:/ o7 j; ?" ^  c
                {nLevel=0x100; nERR=1;}
% ~, Z- `: K9 G  D1 C8 v# c            }
  k5 K4 C% g/ @: H            if(nLevel==0x100)break;
$ N, |2 I: u  J$ Q9 E8 i; @3 `            if(nLevel&0x10 || istrin>>t[2]){+ w# P+ \* T' p+ P
                nLevel &= 0xF;
& G, D! ?7 s) J( f0 n                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}) [: @) L# K0 T, M1 t. v9 `
                if(csym[1]=='*'||csym[1]=='/'){- e/ p3 [4 D. v6 g  v
                    GetExpValue(t+1, csym[1]);3 U5 s- U  V) s$ Z5 r* @0 A
                }
0 E9 P9 d" _% j4 H* d                else{! U" n# Z" A& |- T& y# ]9 w$ O
                    GetExpValue(t, csym[0]);
( D2 l4 h; v2 _                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;/ y: U* M$ w$ I# q" O! }; k+ P
                }. k8 r1 G+ B* N. l9 ?
                nLevel = 1;
. y% \  {) C; l. h1 g4 p1 @! C" c            }* Z0 h1 @, ]( I2 k
            else istrin.clear();7 t+ ~% |6 ]# e9 s1 _4 Y
        }
7 B) Z0 ~3 P. X/ c5 B        else{nERR = -1; break;}
8 J* d. G4 q, s5 v: m    }0 D" Q. [9 R& }: ?! u0 k9 t
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);5 I4 x; [6 `! P+ [; m
    else nReturn=GetExpValue(t, csym[0]);9 |6 X3 c- l  V# g+ \' }, b
    return nERR==-1?1:0;
1 l' |8 y4 b$ v' @4 d4 Y}}/ R$ q7 K, Q( J* m: W& Z
1 P" ]3 Z* b2 i  f* l
. I7 S+ ?! N# b  D9 C8 U

( j; d: \' V6 C- j函数模板使用示例:+ o% M: _0 _# Y$ _2 l5 n
在以上那段代码的后面加上以下代码:
, f2 z9 V: H0 B& r4 v* R: K, w0 a/ \. R- z  Q% _; h4 j" \
8 p; I% w5 v9 y: R5 Z

  ~4 n* f* w* C程序代码:
) O" A* g2 ~. J8 C: J. s1 \4 w1 F6 \7 @+ l) d
#include<strstream>" R- w6 n; D) M7 T) I7 p" v
#include<iostream>0 u9 f* i$ f- A. I& |4 m' N
#include<string>$ h: j2 v6 C# p9 p: q& E
using namespace std;
5 B! L9 a) |5 K7 [* {7 j: P- [int main(void)
% x0 d. ~( N6 a) I/ j( [8 d2 V! O( S7 p{
5 m" q& T( o( Y& ~$ Z    string s1;
! C5 h+ [" s+ ~) @) ~4 g8 B" d    while(cin>>s1). I0 p' f1 w1 m  M! k: J
    {' W& V' I# s  y0 g9 ^3 W
        istrstream isin(s1.data());
( `0 X' `5 c- B/ V: |. e        double d;- \1 C/ e6 e* ^: c. I$ x- b
        if(fy_Exp::GetExpValue(isin, d))" M2 a1 O7 I5 u
        {1 W9 d4 {5 M0 m& j
            cout<<d<<endl;
. ?1 J- `0 k- z7 U) n; I" s        }  _2 b, t- f' R0 V) u
        else, f! P3 R) i5 y2 _1 B6 [8 J6 v+ c
        {
) M1 a. S: s! p3 [! n. v            cout<<"ERROR"<<endl;/ a' |* ~0 a! x6 K( o( g0 y
        }
2 a4 [( {$ U; e) W8 \8 C    }) D0 ~; n  p. g4 z5 j. N$ D
    return 0;
7 M: v7 V) Z* M3 v4 W' \0 @}8 U1 r, _: ]" a' F9 `+ S
" e. a2 I  Y7 U4 u* ^( [! n+ o
7 L( i+ f, [" d; M
然后编译执行就可以了(*^_^*), P  c  ^$ F% g5 h/ C3 f' R0 J
其它:TC++上一定编译错误,不保证在VC6上也能通过编译9 K& E6 i; y# V
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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