返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,6 S) L  z- h$ V7 e& f8 J
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式  g9 E& y+ {. q* @( b; \
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
% [; y  W5 f: G0 ?5 v' x% t参数解释:
( G, P; c5 ^! Z. |8 ristrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流) }) K& s) m& k5 X) e0 D+ t
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定( K9 u5 s0 ?/ \) {- \/ Z  ~
返回值:
( w) W) a) f5 T- R& Y8 y2 b7 h+ m返回非0表示计算成功,0表示计算失败有错误1 s3 ~9 L8 Q5 @( J9 {, _: U% O
1 P, H- ?1 l; \! I* {% M1 e) r
2 @" J) d% V  G4 P- f
! v! h# c. q7 f) i4 u1 }
程序代码: ' @# r& u5 P7 q' W  ^+ y
, a* w) I5 c$ s2 [7 T
namespace fy_Exp{3 u1 [6 [5 k0 ?- L3 d2 K' F  W
namespace {template <class _T>
) R5 Z! v, ~: [! v; I; _0 Binline _T GetExpValue(_T t[], char& csym){% N- E5 i; Z' t6 n
    char c=csym; csym=0;
( T7 j0 g" l- y) H8 v1 f4 F4 m, G    switch(c){
* K, @. q; s! W2 ^9 h    case '+':return t[0] += t[1];
" Z) O4 C" B0 p1 r! [    case '-':return t[0] -= t[1];
8 \1 x% O: C; N3 p; P    case '*':return t[0] *= t[1];/ W' ]5 G) ]  P# F2 M! Z) S
    default: return t[0] /= t[1];//case '/':
" I/ o4 V) z5 K8 g( Z    }6 o) ^' [" M; Z4 u* u5 H5 h
}}: \7 W: Y0 K; H
template <class _T, class _Tstream>
0 p5 a/ J* H( A+ i/* _Tstream: inputstream, _T: get return value
& e2 Q4 I& l. E; I+ @* Return nonzero if get value successfully */
8 l8 s( A/ H; @( p; {# nint GetExpValue(_Tstream& istrin, _T& nReturn){# G% J; @$ K/ o% Z0 k) b
    _T t[3] = {0}; //雨中飞燕之作
8 ^& r% ?9 {1 i' a$ n9 a    char csym[3] = "++";
2 ], S* Z4 \3 Z9 M4 _6 _    int nLevel = 1, nERR = 0;
4 ~- U7 F) Y! s7 M, @    if(!(istrin>>t[1]))istrin.clear();1 j: \& f" @1 w3 ?# y
    for(;;){2 E& ^- u  u! v0 `5 d& [3 Q+ V; v
        if(istrin>>csym[2]){% ~5 N" ]4 z  h
            switch(csym[2]){
9 L8 ?7 x  p* j" j1 ]            case '(':
  b$ D% W& d7 p3 M                if(!csym[1]){nLevel=0x100; nERR=1;}else
5 P; O* ?& A6 K. w, s/ s7 w0 ~, U                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
8 ^' n8 }$ d3 t. L1 Y/ e' |                else{nLevel=0x100; nERR=1;}
7 r' c5 S: \1 z% }. z. b4 x$ [: K( B                break;
/ d; [( W8 G( S+ _# D) |. f            case ')':
: X8 y8 n( h8 I! ?# v; m- a                {nLevel = 0x100;}break;; g( u3 P& Z5 K
            case '+':case '-':case '*':case '/':
3 [- V5 l3 N; |- g/ m/ E" ~9 Y                {csym[nLevel++] = csym[2];}break;6 Q! |8 e$ Y( D& P, u6 \
            case ' ':case '\r':case '\n':case '\t':continue;
/ x0 b6 h( g+ W. v- C            default:
+ }- i0 V* }5 U& D" A0 n                {nLevel=0x100; nERR=1;}
  K# N2 M7 q& }& s6 n3 }& ^            }- y+ L  r4 ^2 v, }( h4 l  c- ]" n5 X
            if(nLevel==0x100)break;) O, Z/ {! }: y( k% _
            if(nLevel&0x10 || istrin>>t[2]){
9 |' f2 T  q9 o) `( Q  `                nLevel &= 0xF;4 B* b2 s% c4 n, c' E6 I
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
5 f9 S( O* D8 e1 C+ m# c- ^- v                if(csym[1]=='*'||csym[1]=='/'){
+ j( b( n3 F, Q' D! j                    GetExpValue(t+1, csym[1]);
3 U1 J8 ?; R9 f                }
  z2 r! G4 U& b5 q2 D                else{! E  o3 o0 E: l+ k6 k5 b9 o) h
                    GetExpValue(t, csym[0]);/ z, ?+ R. M0 R3 ~, T
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
" z2 V! t) B  q6 M                }
; |$ X) F  h/ l  p: s* y( l& g" O* B                nLevel = 1;
- q* X  \& W& ]            }8 u3 P2 R% H; D) Q2 b3 Y" |6 j1 C4 F
            else istrin.clear();. l9 D8 s! s. Y. |* F
        }) X3 n3 M1 k) }# f
        else{nERR = -1; break;}5 T, U: o' I' N* ~
    }
4 V# ~& n& @6 H, m4 \( O    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
3 F0 w) @" R2 n  H6 G# L, w    else nReturn=GetExpValue(t, csym[0]);
* M; C; T4 {9 f    return nERR==-1?1:0;1 i3 x& N# B. i3 E
}}
' X8 E% l. s( a) }, ~0 P" F/ a, r/ ~8 c+ [8 y! t

1 @' O( I+ v9 w
7 _" V& q, V* _, H9 l函数模板使用示例:: z) g+ A6 M" u
在以上那段代码的后面加上以下代码:2 i* X' x/ k2 n4 q  W

2 q, c, s  ]% k1 z # Y0 [1 `; V  X! J' x- [0 d

6 x) o3 s/ ~5 N* {1 d程序代码:   c* N- k- k/ G) ~; ^, A0 C

* e2 }/ M# T1 v6 ?: B#include<strstream>) K# o0 S* v5 H0 v# h9 g* ]( U
#include<iostream>
6 v+ ^& ]; G) g* O#include<string>5 l6 V$ g' s$ d% Q
using namespace std;% [. d5 |$ H5 n: Y0 ~4 U+ ]; z
int main(void)" T3 o- N2 X# j: D5 m5 ~+ l
{
6 n$ J4 U1 p1 M/ M. Q% O: V* O    string s1;9 {: W, B' D. l8 X- C3 i) K
    while(cin>>s1)
) P) X! [, i! Z* G  x) i% e! K    {4 h+ W0 j1 V6 S. ?  T- ?
        istrstream isin(s1.data());  ?% ^0 v; b% D" T
        double d;1 T3 F- N; E/ j2 |
        if(fy_Exp::GetExpValue(isin, d))
* k. n# Z- G' Q        {
! c- R/ l+ [8 s0 U( J) P0 w            cout<<d<<endl;9 h' ]- u* {( R% N7 R3 X% W
        }
$ D+ A3 C+ |" z( l: }2 |        else, @, [. I. ^% {- R4 u1 t* Q2 S
        {
1 c/ N4 {7 K. g% B# `% o) g3 H$ I4 _$ Q            cout<<"ERROR"<<endl;
" z1 w3 i* ?$ C% O        }+ u' F7 _( o, j3 A7 `2 s
    }/ t1 {+ |5 I% {( \' H  V( a
    return 0;/ A( O& m6 b, t* V5 w* u0 N- ]
}6 g, m4 J. F- B  F* b) o. w

8 u9 D$ y5 \8 B. m) j/ s
7 \5 G. s  e8 c% H& V, O然后编译执行就可以了(*^_^*)
+ v' S' v/ `* a: ]3 ~* p$ }1 n5 v% M其它:TC++上一定编译错误,不保证在VC6上也能通过编译
# A& ^1 w2 p3 l0 B      建议使用VC7或VC更高版本,或者使用GNU C++编译

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