返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,- e' f# }& l, j3 m: n& \
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
& J$ W3 o, P6 R) c只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
) S. a7 e5 l. f* f# a3 s参数解释:+ ^% U# v7 @# U
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
/ ?( h6 ]: r; ^0 Z7 q& MnReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定% c% g7 M( @9 o
返回值:
; C: `, p* h; ^5 K返回非0表示计算成功,0表示计算失败有错误; d- V# O5 U- i. m) m/ J0 R
  I9 f! }2 C1 m1 {7 b* ?6 f; y
5 E+ X  t3 ~5 M0 H5 x4 e

& d* \6 m. J7 ^$ P; q程序代码:
6 z7 s5 [- q1 X5 y* ~4 G* n7 J) C; J& v
namespace fy_Exp{' V2 N# |/ x0 U0 \% L& J. ~9 o' m
namespace {template <class _T>3 V4 m: h0 U: |: u8 b' H+ K
inline _T GetExpValue(_T t[], char& csym){. \( G  Y+ g* w: ?( ^9 ~' J& `9 T. f
    char c=csym; csym=0;  J$ a9 ?$ W" |7 X% f- B
    switch(c){) R  ?5 C. y* d# y
    case '+':return t[0] += t[1];0 g8 z5 P( U7 n7 }
    case '-':return t[0] -= t[1];: ~" ~+ b) D$ s  Y  U
    case '*':return t[0] *= t[1];0 W# x* |1 f" ]+ u, e. x( J4 z" Y
    default: return t[0] /= t[1];//case '/':4 S5 c8 p# h& Y# r8 L
    }
8 Q' F$ d8 e. Y& F- y. h}}1 S/ w  {5 m& D: ?$ r
template <class _T, class _Tstream>
. x0 B3 p, a: Z7 p3 x/* _Tstream: inputstream, _T: get return value
& P9 ]) A8 G  \9 N3 T* B: X6 s6 W* Return nonzero if get value successfully */$ a9 B) j2 x8 l9 z+ P
int GetExpValue(_Tstream& istrin, _T& nReturn){, W/ b) z6 I, c& s& ?
    _T t[3] = {0}; //雨中飞燕之作' I  ?2 ]" E, B1 D; T9 v
    char csym[3] = "++";
8 s. z9 {3 o, N, Z2 Q; _" E    int nLevel = 1, nERR = 0;
1 X) g- {+ [  |' u9 m2 W* a- R6 b0 m  T    if(!(istrin>>t[1]))istrin.clear();- u' y5 t7 V& d! T8 e
    for(;;){
$ ^. n8 x$ b1 z  y  D        if(istrin>>csym[2]){
% i1 ~* @/ R2 ^7 r0 R            switch(csym[2]){/ M' h, f0 E  n
            case '(':* B; j$ h: ~) r
                if(!csym[1]){nLevel=0x100; nERR=1;}else3 m) j3 A  T3 i4 _5 F2 w8 T
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;) U/ m9 o( i/ ]7 {3 m; e
                else{nLevel=0x100; nERR=1;}2 G; @" [  n  D/ I
                break;
. `0 j+ T4 `+ v1 A2 y/ a            case ')':" L: q) v4 n8 U# ], m* Z+ g$ T
                {nLevel = 0x100;}break;/ C0 @" W; \0 T: |0 |4 }- _( y
            case '+':case '-':case '*':case '/':
# E( D# e; d( l5 q" ]8 V; U                {csym[nLevel++] = csym[2];}break;% S# q9 u8 a+ z1 b0 }+ M# F
            case ' ':case '\r':case '\n':case '\t':continue;0 r0 K. h+ o: y; m' \2 v
            default:0 d% I/ I( ~: Q5 y* E8 t
                {nLevel=0x100; nERR=1;}
( d. Q0 f6 a0 c; U! ^$ c            }* F, ?  D2 v2 B* Y4 b1 q: @
            if(nLevel==0x100)break;, l: w3 e) r" M6 U, @$ X( ?
            if(nLevel&0x10 || istrin>>t[2]){# |( ?9 ^1 I% m
                nLevel &= 0xF;
+ [7 @' W# V+ @* V# I. a6 x                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
8 b1 c* o: Q- r% x& B                if(csym[1]=='*'||csym[1]=='/'){( |0 A; J% O6 v# c; f
                    GetExpValue(t+1, csym[1]);3 H4 m! b) D2 t
                }( b. \* b, X: _6 S1 W
                else{4 K: s  C/ }$ }1 A& B: v
                    GetExpValue(t, csym[0]);+ ?% Z6 `; B' J' ~9 w' z! d, q7 x
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
9 o& n  J: ?0 _; Z! p/ }0 C                }
6 S: X3 s& C$ X; h* d) u% T                nLevel = 1;
* F$ ~! T& a7 x' N4 ?9 Z            }6 [. Z: u! z# |5 R# Q6 ^8 z
            else istrin.clear();: L( \1 I/ a- t% v- E- O6 ]2 q2 q
        }
0 Z! I& B* R: m0 E        else{nERR = -1; break;}
9 G1 w* K* G: G& ~0 u8 ^1 }3 @    }
6 {$ L9 u* h, p+ l( f    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
. N7 _) V) o0 b" p$ a! n0 Q1 G    else nReturn=GetExpValue(t, csym[0]);
6 X0 ]+ M+ S. ]0 w    return nERR==-1?1:0;
% D- r8 w) u! ]/ N9 E& l}}
  o2 X# R2 y" V8 \' f) w( N$ S# Z1 Q0 q
2 N/ G; C9 u4 U9 q) n
, ^' T6 [  N/ u
函数模板使用示例:
/ k. U6 a4 V  _0 `9 w在以上那段代码的后面加上以下代码:6 L% v$ y3 \7 K9 K
: O  m. ]% g. s

6 t% h8 C* }* ?( ^0 O6 _
9 j  n$ y# m7 _; n: \5 D7 Q  q程序代码:
& g% g: h4 v) n" L$ e0 N% O' p' o  t+ q, W1 v+ L" q
#include<strstream>
9 f) z  [, h3 K+ Z2 d) o#include<iostream>
# h9 V# t4 @8 |' h& F#include<string>
* L. `3 G( n4 Z* Kusing namespace std;
& j! ]$ [, I( p7 O4 t; m, dint main(void)
' H9 \. ]& A1 [2 i{4 A& |7 P; y% Q# N0 E3 F/ M
    string s1;
/ J  b% V( d) v    while(cin>>s1). q3 B$ C3 O& Z4 M: E
    {# {# s5 F8 Z1 x$ H$ ]
        istrstream isin(s1.data());
, A9 H4 _# |" x5 I2 c8 j        double d;: l2 z$ G$ I! |; g6 z
        if(fy_Exp::GetExpValue(isin, d))" ^% w1 }# X! k& }5 ~
        {1 A# p( _) j" Z, ^, |: I
            cout<<d<<endl;
& Q7 u( V) N. p) S6 \! W! n        }
& c. f# `* l2 W: ?; E        else
6 e0 C. N* p- E8 Z        {$ `6 a& J5 F4 z- S
            cout<<"ERROR"<<endl;
1 [: n8 q8 `% c$ q; }0 u( A        }8 z' X! K6 q; C2 C) r9 B3 D+ j
    }2 Z% p% y7 r/ y2 P+ N
    return 0;
/ z; f+ D# j& k; W: u1 z}* i: b: E4 |" v* Y, r2 d

5 d) W0 `% W- [# c1 n$ r7 G8 j# h( q8 I$ Z
然后编译执行就可以了(*^_^*)
; M5 g0 P, x8 O- A5 [其它:TC++上一定编译错误,不保证在VC6上也能通过编译0 k- d! w. j* z1 B* V/ z# G
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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