返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
/ h+ B2 C% R0 Q' q4 j; B一个很方便的函数模板,可以并且只可以计算含括号的四则表达式5 K& p+ i+ H. b( X6 }3 _( L- u
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)" q$ l! r' s1 n2 _: a, K! I  x5 z# {$ e
参数解释:4 P9 L8 W- I" p" Z
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流  H' g' H! K, Q* Z2 F8 E/ g
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定' F' A9 Q& U3 L  e/ i
返回值:
+ C  s* z, b" i* q& p返回非0表示计算成功,0表示计算失败有错误. _; n0 d3 l% }& E6 C" A9 c' v: d

6 g' u% o# F" l* N$ I; G ( y) b5 U7 Q' J: M, W! n
" Z- ]0 M% C" J) a& S+ Z+ t
程序代码: / l# @9 N# q& V5 t3 c1 O
) P8 T8 s* w/ _& C3 U% h! T
namespace fy_Exp{% H: x6 K3 B/ M5 U' `# U
namespace {template <class _T>* M1 d& V$ w8 O7 s
inline _T GetExpValue(_T t[], char& csym){
1 R  w& V2 D: s. ?- m1 V0 K3 q' s5 j5 u    char c=csym; csym=0;
6 \" S/ }  G+ R# f: f+ n% ?0 ]3 W    switch(c){) f5 P9 ~+ }+ W6 Y, A( ^
    case '+':return t[0] += t[1];$ h, ^" c' [/ R
    case '-':return t[0] -= t[1];
, N! R, f$ P5 [    case '*':return t[0] *= t[1];
7 d1 s6 J& ^4 k5 X    default: return t[0] /= t[1];//case '/':
! q0 f, y$ c' ~/ O. z* l    }
# U& M- S" t/ G4 S3 ~) G}}
+ n" K4 g  c3 ^- N5 U) Ttemplate <class _T, class _Tstream>
% s% W- }" {$ Y: V# E8 y/* _Tstream: inputstream, _T: get return value4 o1 Z$ d& ^  O  }' k1 N
* Return nonzero if get value successfully */
3 N; U+ M( u' S7 Y! [8 Jint GetExpValue(_Tstream& istrin, _T& nReturn){; j% H, a/ A! T9 X9 u3 E; W
    _T t[3] = {0}; //雨中飞燕之作
& I( t1 B8 E' H+ v  a2 }3 Y! y    char csym[3] = "++";3 T% T1 T: Z$ c& o* C, Z6 i7 ^. L. B
    int nLevel = 1, nERR = 0;
& t( F( V7 X+ O" w  O1 B    if(!(istrin>>t[1]))istrin.clear();
) Q# k6 N4 I$ J2 r) a1 H    for(;;){2 E; y% h+ \& j) C5 n  r9 A
        if(istrin>>csym[2]){: M& h) g$ |" y* c* v- {5 y* \( F% C
            switch(csym[2]){
, k' D& b% f# L& w( `) X            case '(':
+ g& n9 u# M+ L) R$ Z                if(!csym[1]){nLevel=0x100; nERR=1;}else8 a7 h* P+ V3 M8 f7 J/ T/ w
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
( n: T$ H8 u! x                else{nLevel=0x100; nERR=1;}9 o2 W0 O& t6 }& ?1 E' [
                break;
& ?( t/ b9 b; d  }; t: |            case ')':4 x: D8 f& q" x2 s1 E2 i
                {nLevel = 0x100;}break;0 }- e8 n" l/ q) w" ~
            case '+':case '-':case '*':case '/':, H- [8 Y+ n+ T6 W) |
                {csym[nLevel++] = csym[2];}break;, L- J$ S; s: P/ p
            case ' ':case '\r':case '\n':case '\t':continue;$ \4 p. h- H, `1 w
            default:
) }! a: J$ x5 n# ]4 I1 P6 J                {nLevel=0x100; nERR=1;}4 H5 t# t7 b' p6 k2 D1 {
            }
- r8 ]$ c" Q- u1 o4 ], O% D            if(nLevel==0x100)break;
  C. r9 Z+ X1 Q5 q8 I2 U            if(nLevel&0x10 || istrin>>t[2]){% X& v2 I/ P9 H7 e% g% e
                nLevel &= 0xF;
1 t$ O3 r" s0 U! k7 W                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}8 F; G$ j/ ^, P) d  L- |2 W3 {/ N
                if(csym[1]=='*'||csym[1]=='/'){
$ z  Y! @& ~7 L% ?$ {" ?                    GetExpValue(t+1, csym[1]);2 A. D6 ?" i. v2 t5 N5 |
                }' Z6 F, w; o; J8 ]8 u2 N$ h
                else{
# i! h: [+ c+ \. B1 c! A! I9 b" x                    GetExpValue(t, csym[0]);! s1 s7 I/ ^/ P# E( L, E
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
5 }, @" ]! t5 _# _4 _                }: r% D9 o( {6 F' v5 @, A
                nLevel = 1;
- H1 Y3 C5 h" @2 ?+ y            }& b; J) K& |! t
            else istrin.clear();8 K# @2 ?/ c, e( [# v
        }
0 J7 Q$ A/ F  l1 t1 j, O        else{nERR = -1; break;}: F/ C& N! d; c+ B5 F5 d7 D5 y" J
    }. o! ?6 v6 A$ F+ T
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
& Z' B9 s  x8 X! e' D+ u    else nReturn=GetExpValue(t, csym[0]);- n" m9 j& j" R) ?. g, X
    return nERR==-1?1:0;
' i) r: p1 M' G. v& e}}+ \9 q4 m" k" @$ M# i
* l/ C! H) p) u: ~8 F9 ?1 w0 F

! N6 ]& z% x9 k! t, E! a- L
0 J6 {- `' f; q: |; Z函数模板使用示例:. q2 I/ Q' |1 y2 V5 g# P" o/ }
在以上那段代码的后面加上以下代码:
6 `' d3 Z6 A# F1 T+ w5 \1 T
% `3 `1 {6 s% d
  n& J6 h* w. i9 e& Z8 }% X( B& L) B+ d/ u) `6 v9 f+ c/ f0 X' F: A
程序代码:
9 ^( d" E9 T0 ?' S* z0 k2 R: C( p8 r4 g2 k9 Z8 g
#include<strstream>
, u1 ?! w6 \, \* k8 f#include<iostream>
# G" L. o( L4 \#include<string>
3 m! o+ s$ ^  {: L. ausing namespace std;
# d5 n! d) B  @2 _  \$ cint main(void); e4 t7 F  t& w6 |) s, p3 T) G
{1 k4 Y/ A/ l% z
    string s1;
6 V; r) M' v7 J' p( W+ Z+ w' s    while(cin>>s1)% s" ?7 j7 K! d' m: ~% W" Y
    {
1 \/ w0 L% a6 \- s' s: I        istrstream isin(s1.data());* U1 X/ E0 U6 m5 C- o5 t( m
        double d;- Y7 G$ v9 `4 X5 s2 i
        if(fy_Exp::GetExpValue(isin, d))
' Y) R, w8 h8 r3 I' e        {
2 F% K0 ]. J- x  B$ ]) N$ X            cout<<d<<endl;, \- Y8 }! M/ f' _0 Y
        }
* X( z4 C+ M5 u, D% f9 t        else
# v$ f. C1 u9 u( v/ @) f        {
0 ?- [2 T+ T- k$ B7 Y            cout<<"ERROR"<<endl;
/ f# v5 ?/ L: F! p) P# j        }
9 c9 {. I0 f! a5 g3 m* b/ T    }
2 L" g/ w. x$ w0 C2 H3 B- r% g    return 0;
, g8 @: A2 D( _* S) A! }}6 Q8 Y5 U0 R- z8 Q4 }) ^
, f9 B( m  l' K8 A- H) X/ z* _

! L! m9 A0 Q. }5 }$ }: p然后编译执行就可以了(*^_^*)) R7 w$ h+ A$ P/ d0 ^+ J
其它:TC++上一定编译错误,不保证在VC6上也能通过编译
# @( w' S2 y7 j. i# n      建议使用VC7或VC更高版本,或者使用GNU C++编译

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