返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
$ y# k( H. k) Q; e  }  ?1 T+ q$ O( J一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
$ g0 S! D. _0 k/ g+ T% v8 Y只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)5 r1 l! Q  n3 y7 W3 R% i/ T
参数解释:
, ~) K3 Z- s) E; d! [4 Distrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流. C: o& U/ y; C8 C' R$ w3 b2 s
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定" k3 I' l6 J8 x2 B
返回值:& r6 Q/ M6 D% W( ?# m5 q; a- U% h- x! l
返回非0表示计算成功,0表示计算失败有错误  Q' D5 Y7 ~0 ^# I! w

( V1 l! t8 d! e9 L: C+ Z1 [ # ~) ?8 x' X- v7 w3 }+ o$ p

+ Y4 C3 R3 W/ u5 O* m程序代码: 9 z% X: F4 C% I9 T: t# l/ ]
- r% e6 `7 t2 Z/ m3 X
namespace fy_Exp{
" `) P6 H, S! r+ ~namespace {template <class _T>7 l" D" e! r/ m- W. K; n! Y
inline _T GetExpValue(_T t[], char& csym){: d% ?! C8 ?# D: ]7 v0 F# V# Z
    char c=csym; csym=0;0 S# |9 q/ W& I& @( ^  S) I# a
    switch(c){3 b4 D3 _; l) R
    case '+':return t[0] += t[1];  s# n+ ?4 t9 L: A( ~
    case '-':return t[0] -= t[1];
: n3 @# V  Q, Q' x* [    case '*':return t[0] *= t[1];' R- n8 u; b0 p' p# c' Y4 }
    default: return t[0] /= t[1];//case '/':
% M8 \& B1 y. T2 o( N+ V    }/ Q7 @( S6 L  z1 Z. |0 m
}}' j) l  V4 x* \* N# g( L# Q% H0 ~, a
template <class _T, class _Tstream>& N/ c1 z1 }& m: [* k0 U$ u
/* _Tstream: inputstream, _T: get return value) g, r. W7 c. |7 i  j
* Return nonzero if get value successfully */2 y( O- a( h. n0 U; |  }& K
int GetExpValue(_Tstream& istrin, _T& nReturn){
4 z! Y$ Q7 j; |( ]( _% @    _T t[3] = {0}; //雨中飞燕之作
( R4 o8 t7 ^8 E! J- z" v& u. N1 F; _% A    char csym[3] = "++";
  E# S- v0 L8 i0 t) o    int nLevel = 1, nERR = 0;
' t; Z3 @' ]& ]( t    if(!(istrin>>t[1]))istrin.clear();
8 v8 w8 |: f0 U1 k* K    for(;;){
; v6 X- @! i6 `) j' X        if(istrin>>csym[2]){
& a5 j3 m4 H2 d, {3 i& I            switch(csym[2]){
/ T% L0 n  d" M! i/ T4 S! ^; N2 Y            case '(':
  {- v6 {# ?7 F, K. B( M+ B                if(!csym[1]){nLevel=0x100; nERR=1;}else: E" N5 e& ~8 ~8 R/ H
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;" ^, `( }- e; ^" `
                else{nLevel=0x100; nERR=1;}
5 |  B' s2 y5 Z0 Q                break;
( [8 V% ^7 q7 g& j1 _            case ')':0 [8 j* c: \( O  @5 O7 k) K
                {nLevel = 0x100;}break;
4 s! h% i* |" V9 D! |            case '+':case '-':case '*':case '/':
/ {2 ^) u# o: X" J7 |; Z1 c                {csym[nLevel++] = csym[2];}break;
1 w1 k4 [& \  q& ?            case ' ':case '\r':case '\n':case '\t':continue;
6 _' _* n( w) r/ M4 E) y9 t& g            default:
. G" w6 v0 k. {4 t: i& l% {& h                {nLevel=0x100; nERR=1;}1 U  y. \2 [7 L6 e1 y# o
            }
' g& h1 N) D/ V, x. D! Z! A; ^            if(nLevel==0x100)break;
# g1 V3 m9 t/ V- U" _5 E! |+ ~6 @            if(nLevel&0x10 || istrin>>t[2]){
7 H/ Y1 ?" y, Y; R9 K* }; M0 [                nLevel &= 0xF;, l2 \8 B- Y& Q/ ?9 @6 p8 c, h- e% n
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
( \: ?# O. y, c: H6 c. J6 g% X                if(csym[1]=='*'||csym[1]=='/'){' d( _' ~  C1 b0 c# s, S
                    GetExpValue(t+1, csym[1]);
( v3 F; a1 v# X1 W0 _) T0 p0 c* J                }
6 o' w4 K* A. Q" W! H                else{: B! D3 y/ s) _* [
                    GetExpValue(t, csym[0]);, r6 ]* i, `( o
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
" j( j, o6 A+ g                }
/ H, K2 k' _# r% S                nLevel = 1;0 J, E1 }9 N& Y
            }" Y9 P2 d  v' ^; p0 H. x8 A
            else istrin.clear();6 h; u9 n, f7 ~% ~" O5 M& X
        }$ U- G( L2 f4 k! M* |' ]; b
        else{nERR = -1; break;}# Q% m5 p- {+ W
    }' q# r; n; u0 i' W
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);* R# z* i, q- S9 x* p, J+ n9 {
    else nReturn=GetExpValue(t, csym[0]);
0 z0 q* v/ G& |$ B    return nERR==-1?1:0;
' M" P  g$ W4 e9 T' k0 U- O}}. L/ Q" |$ H' O* }$ w5 D: p% O

1 c  D- Z  }( k5 e- {8 Z: R0 d
3 h& c. b. _7 s$ t
- e" V% n0 J% n9 c" {函数模板使用示例:
3 ]  O) J9 _/ v5 m) A在以上那段代码的后面加上以下代码:
" e) O; a( U1 c  @1 b
2 n- }$ \6 o2 W
, Y9 u8 J7 E7 a" T: p, Z+ v, h, q' y  F; o- v- G$ H/ j
程序代码:
2 K) X8 T. X$ _) k6 T+ S6 B3 m- D1 g% s
#include<strstream>
! ~: p6 q/ @& j9 C3 D+ N5 T#include<iostream>2 _* R6 O3 g5 _  B5 y! g/ V
#include<string>
1 c' J0 o3 {; z, f+ F) pusing namespace std;
$ t1 b; h! I' {$ eint main(void)
! h/ q* [+ {! [{
1 o# q( j& _- c9 `2 V    string s1;
* F/ ~5 I' ~1 j& A3 D+ z    while(cin>>s1)
8 p- q! F: g8 y. r    {- M8 @  x+ }* R, m8 ~- [$ f
        istrstream isin(s1.data());8 N" F& o! I, u) i& s% X0 l
        double d;. I  ]% ~, ]6 ]0 [$ n$ v" `
        if(fy_Exp::GetExpValue(isin, d))$ g9 D/ w$ E$ a
        {5 Q4 _2 X) m3 z3 b0 u8 D
            cout<<d<<endl;2 `; j8 r, P/ F' N+ X
        }" L9 z5 q; \% g( t# Q; e5 ^0 t
        else
' G& U5 K& E, U! [! {        {
; \7 s/ B5 Z" H9 V8 P            cout<<"ERROR"<<endl;4 v4 v: B9 m. D5 Z9 Q
        }
: N4 F) w6 p; {* \. p0 m  I- t    }
. O* @% I# X: L    return 0;
3 i+ ~. M# r( J. A5 |1 \}
0 z+ {; h( S! ^2 k% [! K& S4 i0 @' c! n/ O9 ^7 ^# K. J% c

9 b7 W5 x. y* [5 w然后编译执行就可以了(*^_^*)
5 G0 @3 l9 f6 A: ?* U; ~其它:TC++上一定编译错误,不保证在VC6上也能通过编译  q; Z% K5 }# k! a6 C
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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