返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,% P' O% K% l1 G1 ^6 {
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
' P  L- J& A) V9 y7 J) F8 C7 ~只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
# N0 \& Y6 e) r; \" J  U2 x% r参数解释:" o7 G# T+ i7 }2 V
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
/ p* m3 \/ \- ~& y$ `8 Z  [nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
9 n% }5 v, H, S% O; S+ [" `: L返回值:
4 ^2 g" N) @0 R& [- A5 C返回非0表示计算成功,0表示计算失败有错误- E7 W" w; |$ F+ W6 A2 ~/ ~  ^$ y2 \; N- ]
% r3 i; S9 N. D2 x! `

8 ^* z2 l1 T7 Y/ p
; y8 R1 C% n/ b/ T; ~/ s6 d程序代码: # i1 L) E& p4 m4 t, L6 \1 B) j) I
( ~; b+ _. U+ p3 z
namespace fy_Exp{: y  h9 s1 n  y+ ?7 ~* Q8 @4 R  m1 q( J
namespace {template <class _T>
& ?/ [( S5 Q+ jinline _T GetExpValue(_T t[], char& csym){: |6 C( d8 C. ?1 r, C& D
    char c=csym; csym=0;- m5 l) t8 j8 u5 j4 N
    switch(c){
; `7 E# b$ F/ r5 j6 R    case '+':return t[0] += t[1];' [% r$ E/ u& N8 p2 p( ^
    case '-':return t[0] -= t[1];
5 j6 U) c  c  B) H1 \0 A; S    case '*':return t[0] *= t[1];2 k1 F8 P  E1 ]
    default: return t[0] /= t[1];//case '/':* b% ]& s& J  D
    }  X# H( S. p% p  s, c4 m
}}3 F, v5 V/ `4 u- a$ ^! v% A% U8 U
template <class _T, class _Tstream>
6 i. S: [9 m) q" q" p: `, j6 T/* _Tstream: inputstream, _T: get return value. W, K. n5 r5 O% V* k  _+ ]
* Return nonzero if get value successfully */
) w0 c6 s$ [$ \3 o7 E. n5 [- R% ^: d9 Q; Bint GetExpValue(_Tstream& istrin, _T& nReturn){
0 h4 \1 N6 {2 h$ C    _T t[3] = {0}; //雨中飞燕之作% g% m) }8 o% ^3 G
    char csym[3] = "++";/ K1 z  L) ~) a: M, h
    int nLevel = 1, nERR = 0;
. B8 ?+ V- V' e( @. C/ {    if(!(istrin>>t[1]))istrin.clear();" |' _$ O) ]* f# a3 s( v
    for(;;){
: @, J$ S3 G* g4 y# D' E, i! L        if(istrin>>csym[2]){/ o3 O2 G, p& s; Q- l
            switch(csym[2]){
- N  M* f, _" Q) G4 x' s            case '(':
6 N- c0 p: j+ c# u                if(!csym[1]){nLevel=0x100; nERR=1;}else8 ]  y2 n0 _2 r% W+ R
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;3 y: ]' P: K6 R& Y3 A) a# f+ m
                else{nLevel=0x100; nERR=1;}
/ W- s1 V: t$ m7 H% F  _                break;
/ A# t5 I7 N# ?, h* c; d) y4 ?% K            case ')':
1 ]+ q: O6 _" H                {nLevel = 0x100;}break;
& i" u, ^: f3 @0 p6 P  O6 Q0 d& V            case '+':case '-':case '*':case '/':& a/ u3 C0 L& [3 c
                {csym[nLevel++] = csym[2];}break;
2 f5 s3 O' T- e& Q1 B2 Y4 r( j            case ' ':case '\r':case '\n':case '\t':continue;; Z: J6 h3 p4 e5 m0 k8 j
            default:
7 ]9 L4 O; g3 M7 P0 O: y1 S2 Y                {nLevel=0x100; nERR=1;}
& Z# Z' L7 ]# B* B/ O3 b/ G- M            }
- g2 Q/ v. S! y; a            if(nLevel==0x100)break;
# i. h% U1 k+ R3 B; B            if(nLevel&0x10 || istrin>>t[2]){5 G, L" ~% `, ~- a) @1 S# i
                nLevel &= 0xF;
4 X' e1 |0 Q, b                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
  C, A5 q9 u6 t# K                if(csym[1]=='*'||csym[1]=='/'){& z, d3 [. A: [5 c6 U
                    GetExpValue(t+1, csym[1]);
4 t" @% K" U6 y& B) i                }) L8 \7 m9 y- a$ i, B& {: X
                else{2 d: M4 v% D  x9 @& d; Y7 V4 y
                    GetExpValue(t, csym[0]);+ ^+ ^) C/ U' u) }( Y
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;8 t! |! c5 c% p, N0 Y4 T
                }% J5 K. r  X* V7 g& I7 j
                nLevel = 1;9 ~% a# k0 I4 F' l! {  J8 K
            }
) s% R/ w% w1 V            else istrin.clear();
; u- V9 r( M5 S0 G# P+ c        }
, |- s2 y. v/ _        else{nERR = -1; break;}' }3 D) L6 H9 n+ v2 W8 [# a) f
    }* m& b) \% }& N
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);1 H3 k  L: r) F3 c+ x0 t7 W' N
    else nReturn=GetExpValue(t, csym[0]);! w) E/ A: Y: U! I5 o; `) Z
    return nERR==-1?1:0;/ E! |% U6 p4 z0 i. b/ U; y
}}( U% b: l6 a$ H; D( f, @

$ U- F2 m, L8 F: h6 m5 e
) M5 D: A& o3 i
+ U8 k9 d% o5 y) W) |4 K' A函数模板使用示例:6 j4 A2 N, W- o) K# e2 m8 D* f( Q
在以上那段代码的后面加上以下代码:3 W! l& f# q1 ?, p/ Q' u
0 s4 P. s. ?. v% _* M( y4 ?. B

! |% g" b/ r! z5 v  K
  R7 \, k+ f) n8 q  ]程序代码: 5 x2 Q4 y9 \& u
6 l+ d% S( }% F. B
#include<strstream>
$ W# U2 F/ Y: K- S# X: s#include<iostream>& t9 z' w' K5 A7 I" s
#include<string>
7 s0 y: Z. [; @& Rusing namespace std;
( e9 l8 s6 W3 ]8 @) ~  eint main(void)
* ?) U; N9 u! I8 _{
) p$ Z) b5 A" e  Z- K* g    string s1;7 Q- C5 A5 }. X: ~* F5 I. U' S. {
    while(cin>>s1)
3 F% P+ J& M" P    {3 h! h% _! V- z2 e1 Q
        istrstream isin(s1.data());
+ N0 [0 P- B$ l        double d;
- }! Z. r3 M. V+ C        if(fy_Exp::GetExpValue(isin, d))/ U( T3 g% u9 ^$ i0 m
        {
: r. ^! g9 o1 \4 z& w            cout<<d<<endl;; L8 V9 R7 J$ G
        }
3 |4 m, J9 a9 V4 K        else
. h) d' F9 Y4 [$ q0 `$ ^% u" N& L        {
9 T& R" C* N9 G7 V; D, m            cout<<"ERROR"<<endl;7 y" s% r' T! J2 k0 Y  |2 |0 L
        }" t# N  V* n1 b6 H1 Q! W( \. P. u
    }0 Q* t1 e, x5 L/ d- A
    return 0;4 a& k# B3 @$ {3 X( [  B% x
}
: k( L1 L! H$ Z8 [9 b; Y- X+ [  \7 `8 n& h% ~, D
1 J. O# |0 x0 A. G& \
然后编译执行就可以了(*^_^*)
. I1 G2 Q3 n  l+ r其它:TC++上一定编译错误,不保证在VC6上也能通过编译: l1 K! a4 f; ~, ^. K
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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