返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
. f/ U4 X/ A: ]一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
: d+ ^8 ]3 @9 K4 E; p: f只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn); e$ \- K' k" q4 W$ J+ ]5 q* y
参数解释:' ~+ R4 T/ f( T& c/ w) T! `
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
5 r2 F8 n0 m, R8 S$ @) Y+ _nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定7 A  V1 M  K) h* h: I7 E$ l, i) q% u0 I
返回值:* L) s: A# S4 T+ A9 M5 o+ W3 }' o
返回非0表示计算成功,0表示计算失败有错误( I: X: ^! N- J7 ?7 V6 t

  M  `% @, e9 h: @; G' ]8 `  n ! R! w( D, y1 [
( Q( \- V* t# z5 X& v. o7 y7 W, f6 f
程序代码:
. t' c, V& {3 Z% A% ?% S/ J0 D; i9 f, O, {6 \
namespace fy_Exp{, y! d7 o' [1 ~/ b4 t# L9 i
namespace {template <class _T>0 u1 b9 p% j; L0 y
inline _T GetExpValue(_T t[], char& csym){+ s. V! K2 P& \. @4 }" A6 S
    char c=csym; csym=0;
( u9 w# i- _% w  b1 o: ?    switch(c){
3 X' Q1 V: O: X7 g- c- A    case '+':return t[0] += t[1];4 ~( Q! [2 {- ?# Y1 [+ Z, `
    case '-':return t[0] -= t[1];3 M7 H5 v3 @9 m! |5 k8 d
    case '*':return t[0] *= t[1];$ A$ ?: B, Q8 G) [: P( m3 i. V: ~' P- v
    default: return t[0] /= t[1];//case '/':
1 f4 x  u1 c5 A1 m    }
; ~' l9 J6 s1 X+ K9 f; R}}9 f9 ?. x5 g- [
template <class _T, class _Tstream>
2 w$ f" P4 i3 O" p5 F/* _Tstream: inputstream, _T: get return value
. a5 V- v: q# I& N3 j; }- }* Return nonzero if get value successfully */
9 t$ }! g% O3 P' y# \int GetExpValue(_Tstream& istrin, _T& nReturn){2 n& ]# |0 X' A( g1 @6 f: z+ g
    _T t[3] = {0}; //雨中飞燕之作
- g; T" W: {* c0 {    char csym[3] = "++";% n4 z% J$ g' _
    int nLevel = 1, nERR = 0;
* k. P# B( J1 p1 N: Z4 d4 p    if(!(istrin>>t[1]))istrin.clear();" `6 N' ?+ \2 ~/ v3 k+ {* D! L/ ]
    for(;;){& C7 S. s/ Z- w) S4 K( V
        if(istrin>>csym[2]){6 }8 p! m+ J7 c& U: E& y
            switch(csym[2]){
+ Y' B( v$ R- ~' ?( E            case '(':5 b' g: D" k1 ?# R, D
                if(!csym[1]){nLevel=0x100; nERR=1;}else
, e& L" t/ g# A! c                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
& P4 u/ n. |2 `, {% m$ k                else{nLevel=0x100; nERR=1;}5 `& d+ J4 D& h% }9 T
                break;
+ ^5 P3 h; \  \( i/ U2 U            case ')':, O/ d+ W4 q# R% m1 x# X! @" H
                {nLevel = 0x100;}break;
4 _+ O% B4 ~' H; N5 }            case '+':case '-':case '*':case '/':
$ V0 }; X3 }* u  d" B                {csym[nLevel++] = csym[2];}break;
2 k: P& c' J; A4 s. O' r- P            case ' ':case '\r':case '\n':case '\t':continue;7 P2 O% n1 P+ k/ i& P! P! q' n5 }
            default:6 b7 z2 ?5 x) M- c5 c
                {nLevel=0x100; nERR=1;}" c# V+ O9 T) ~2 K) H
            }2 f" l4 p% `* D3 l4 @
            if(nLevel==0x100)break;
6 q. r3 g: C7 p% V7 w. _1 E            if(nLevel&0x10 || istrin>>t[2]){
+ i8 J$ V9 U; Y2 j& H8 K' P                nLevel &= 0xF;
( Q" o* E( o0 c; t" `4 r                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}0 c( \2 K  L0 X: ?/ J" _
                if(csym[1]=='*'||csym[1]=='/'){
7 i7 `' x! Y! T/ n% ^8 x                    GetExpValue(t+1, csym[1]);# \( y- k+ s" J8 Z+ z: i! g
                }
4 _0 o. B) D$ ?7 h                else{
  c3 t% O  E" ]  ]5 W                    GetExpValue(t, csym[0]);
5 g$ a6 U; g* C: ~/ g                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;6 B5 @1 L$ ?/ O2 y6 Z
                }
  `. z) t4 }8 `                nLevel = 1;
! L; i, r& i: m  t0 F* Y& T  j            }
" C( r2 b& o- s% o0 _            else istrin.clear();" a. J# b+ O, \9 x" ~9 H4 Q
        }9 i" F& M0 M' G% t+ j& X7 c
        else{nERR = -1; break;}
3 w1 E3 V& V8 g& [    }
6 p; p# C$ b3 o. W( G- v7 Z3 W    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);7 t* s4 `9 j/ L5 V- V5 D
    else nReturn=GetExpValue(t, csym[0]);9 l$ G* [0 p% m+ Q$ g6 f# \2 Z
    return nERR==-1?1:0;  e+ v; K* {2 K6 j- O
}}
# O' a( E6 H' ^4 ~1 ?" Q' |9 R: x3 {/ a, F. l2 @& t2 Q+ |

4 H5 Z6 [! n" q. Y. m0 V& w2 H5 a! }
函数模板使用示例:
+ h( C! E! N8 S# A7 A: W% m在以上那段代码的后面加上以下代码:& C! y  y2 q, R% i/ Q$ [
" A5 y; h4 b2 c; \+ T- B! o

- p- |0 U/ X$ [" K
7 i% ~4 K( Y' ~$ _0 w程序代码:
) S; ~* H% G, Y# E8 d) z! J* Q4 N* V
#include<strstream>
4 ^, a1 ^; U8 J/ i#include<iostream>; r, A( M$ b! a
#include<string>! Y5 l2 a& ?6 C/ x
using namespace std;
% U/ ~. [  [' G& Rint main(void)% R6 b& T* Y4 J: T* M
{0 K8 R' X( G* {% w; l) s( W) [: ~2 T, Q
    string s1;
# L. H! z3 d6 b# ]& P4 u# F/ b    while(cin>>s1)7 J2 M6 m- E( V: Q4 p
    {8 H2 @+ B7 B4 R$ m8 W) p5 j# d
        istrstream isin(s1.data());' A3 ]1 J9 k- F4 Z8 [& ?' h
        double d;
, z: n# w+ L' ?/ |        if(fy_Exp::GetExpValue(isin, d))" B, ]: Q) S6 A7 Q
        {2 s$ q, L3 w/ }% c
            cout<<d<<endl;
9 D& L( Q, b1 D3 _' L- B, |% |7 U        }
' I% m- A/ N4 o/ ~0 g  S        else
" U% m4 D" l0 Q; x& a* d0 t        {
+ v8 b, D: G- o4 w7 v, h8 Z            cout<<"ERROR"<<endl;
  m, y0 j3 e9 Q# k: Q5 H) S        }" T7 F) ]/ I" i
    }/ J* n! _. d% @6 i, S
    return 0;
% b9 D! k" ]" w, n$ o4 ~}& z2 m$ e" H0 y  ^, }! |
6 o, E4 v8 ?# k6 L" G# r/ ?

/ `& Z0 k) [" w: D+ X/ N然后编译执行就可以了(*^_^*)& W2 t/ Y% V$ @8 l
其它:TC++上一定编译错误,不保证在VC6上也能通过编译
1 ^5 m* v' Z* r8 R      建议使用VC7或VC更高版本,或者使用GNU C++编译

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