返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的," Y$ C' U% f1 A) ~6 {% g/ c
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
  S6 N0 {+ J7 Y* M2 l3 F7 l只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
2 D, `! V; _  B& O参数解释:
: V# }# x0 L  O+ T, I1 G; mistrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流& S0 A: y* V' S: N) X
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
+ F6 A/ r# k9 d6 }- D1 t/ E: K1 D. e返回值:
; R1 F* B$ s8 e! g返回非0表示计算成功,0表示计算失败有错误
, }% M6 Z% S8 O* {) \4 B9 w! I3 E2 \5 Z! a

# _8 L) E! Y2 D( d1 G: k
  M" {. p8 X6 y1 R4 P+ o0 N/ f程序代码: - V6 I+ a; x' M* q- v

4 Z; C; N# ]2 w/ Anamespace fy_Exp{: c) B+ ~( V/ T6 W' W# v! y$ q
namespace {template <class _T>
; c6 k" Q& r: O$ G" j/ Vinline _T GetExpValue(_T t[], char& csym){% ]% E3 T4 ]8 k% w: X
    char c=csym; csym=0;
2 k% |* v% \- D    switch(c){; U/ x1 S4 b1 F  P. }  X% t
    case '+':return t[0] += t[1];! M+ e# d% n: b; t: Q
    case '-':return t[0] -= t[1];' Q6 C" W& T2 T5 b: M4 \4 D3 \
    case '*':return t[0] *= t[1];
3 x# W, P5 |8 @. f' @8 W4 T    default: return t[0] /= t[1];//case '/':  t: ^; s6 c& H) s9 W- w0 F1 r( c
    }6 a/ }- _7 H" [' w) }/ v9 N
}}6 E: l, G2 m3 ]1 t
template <class _T, class _Tstream>. H- V, i2 d  X
/* _Tstream: inputstream, _T: get return value
; G. B* T; l4 f5 [& c4 K  c9 C* Return nonzero if get value successfully */
7 C) S% d: C4 w; ?1 Gint GetExpValue(_Tstream& istrin, _T& nReturn){' z6 L9 N! B) F$ m: Y  ]
    _T t[3] = {0}; //雨中飞燕之作# z) C- d9 C& A* e$ w1 E
    char csym[3] = "++";
" K4 S2 S; Q% G8 X5 |3 G% t    int nLevel = 1, nERR = 0;7 |9 z. e" R# C0 _
    if(!(istrin>>t[1]))istrin.clear();
) C/ W- N4 q1 a    for(;;){, K9 o# z9 f( a3 i0 h3 x( f  d
        if(istrin>>csym[2]){
, s- Y0 K4 x3 I  Q4 L            switch(csym[2]){3 h& v+ Y- P( q! P" f2 D* w4 ?. o% s
            case '(':
/ l& n# w# s; T$ ~                if(!csym[1]){nLevel=0x100; nERR=1;}else
' }$ \5 z3 P: r$ |& I( K, c. I                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
; a# Z4 k4 q- r% f                else{nLevel=0x100; nERR=1;}; e- h  A4 x0 z! U6 B' @5 r/ y
                break;9 D3 S) S! D0 O7 k0 @
            case ')':
$ j7 x  H- @: y0 {! m; u                {nLevel = 0x100;}break;% D& O' @4 X. A  R+ s; F+ r$ i
            case '+':case '-':case '*':case '/':$ B, Q& m1 X3 j8 c4 ]( ^5 |) G
                {csym[nLevel++] = csym[2];}break;$ p2 ]1 O0 r. C! t
            case ' ':case '\r':case '\n':case '\t':continue;; \5 u; j6 L8 \
            default:7 T! Y9 E; Y4 `! z' `, s/ n
                {nLevel=0x100; nERR=1;}  o  l6 w, S5 }/ e1 M
            }
. Z/ L, Q, I. P; u' r# Q            if(nLevel==0x100)break;1 `. j- Q0 D( V2 ^8 @( G
            if(nLevel&0x10 || istrin>>t[2]){
+ G6 s) a1 x. C                nLevel &= 0xF;
! g  ?0 `* q$ ?1 P                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
/ U9 F1 s3 Z! m  U* @" h                if(csym[1]=='*'||csym[1]=='/'){4 E# [% ?  C, ?" F3 c+ `
                    GetExpValue(t+1, csym[1]);
! S$ W3 ]5 g& y; a9 i- F6 @                }/ g9 R4 @0 I" O& Z" R0 H
                else{
# \, x% C8 u' L8 O+ I6 ^- Q                    GetExpValue(t, csym[0]);
8 |; v2 A8 F. V" i2 x; {9 y4 E                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
3 A1 |% {' y# a& ]5 R! `2 d9 D                }3 r9 L" Y1 p; r
                nLevel = 1;8 Q( B6 @# W- U  [& |
            }
3 k5 y& v# O7 _+ C            else istrin.clear();
% d: i) O+ u9 i# Z7 @, _  ~        }
; M6 H# b# s( b  m; p3 c6 @; f2 K, g        else{nERR = -1; break;}6 @# H5 w% P; `* o$ K3 _7 M) w) [( P
    }+ ^5 @8 p" L" Q/ H8 c7 e3 |2 ], s
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);. y. o, Q9 n- Y# t6 C' {
    else nReturn=GetExpValue(t, csym[0]);
" e7 b6 r' G$ \    return nERR==-1?1:0;, N9 @) f/ x6 U/ }  w7 e
}}( U: Z$ k/ ~4 h) l# r- I8 f
/ ]' C' X. Q$ l1 ?; l
$ [5 u  o3 @* G9 Q

9 E( I$ K# t9 R函数模板使用示例:
+ K: C$ ~$ P% {. Q/ J( Z在以上那段代码的后面加上以下代码:8 _7 k  D' W% N- N! D# _% B

$ ]* r3 l. N) M' g0 Z) a
" M2 T7 `+ v' N. q% L
6 ]; p  `( N) N  X, N程序代码: & v% K; R9 m  _& @; t
( q- B3 ^6 S. n2 @& x9 [
#include<strstream>8 U6 q# O7 F& I' Q8 S4 l  w- d
#include<iostream>2 L$ o" ]% v$ F/ k1 Q, e
#include<string>( E' ^5 A+ o" ^& d- d" Y( L9 v$ {4 _
using namespace std;
$ a; r: Q2 o) _% Yint main(void)
  U/ |% Z: {- G9 ^$ D6 z6 H/ d: o{
, R$ F. ~) o+ \! d    string s1;. D. i# t+ |0 p& a. z, E5 |* l3 J
    while(cin>>s1)+ G. h+ H" H3 Y0 q
    {
; C% t' |# R1 k& [        istrstream isin(s1.data());
6 J* ^7 u- P6 v4 m) ^9 {, L        double d;
4 N# U# x. x/ t( I# q& D& B        if(fy_Exp::GetExpValue(isin, d))0 o! j5 h- s0 `3 s
        {
0 [& b0 I6 e3 r) K9 d5 Y            cout<<d<<endl;
( c& o" H; `: x        }
2 R2 w8 b+ G6 c7 Y0 r        else
4 L% O2 f4 q1 [9 N1 V        {
, Q! g& u$ T5 T' i* L9 B0 b            cout<<"ERROR"<<endl;  X0 n0 a2 F! d1 B- [# L
        }8 l) y9 e' F& N% c7 B& z6 z4 I+ V
    }
# J9 G/ ]# m0 E/ I  ^    return 0;
" q" f% X( q, }( ?$ U}
- l6 v5 ?7 H# l8 E6 ]: _5 e! Y8 V3 n6 Z: e, A$ B& I+ p

0 U2 K4 ?3 u" z( z# A然后编译执行就可以了(*^_^*). ~  i3 H+ J: Z& @0 X# ^# R6 R( B
其它:TC++上一定编译错误,不保证在VC6上也能通过编译; b4 b6 v/ o! s, q
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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