返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,: M0 c' ~" R6 a6 x" `0 p/ s
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
. f( U- ?7 Y# M& H; h  w3 F/ e只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
2 K  K- e6 }6 ]4 ]; `1 T: w8 }参数解释:
' v# n, Q2 o% {  \- w$ r2 Histrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流+ D) i7 h1 s) Q6 w: ~
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
7 }! J, A; V" }6 m9 [. B  D返回值:, |! Q) g3 c1 z9 p( E8 x9 X% J/ |
返回非0表示计算成功,0表示计算失败有错误  ]( u: U2 T5 T" y$ e  v. \

4 y% F( I% S9 K
5 t7 c1 J+ i) B9 H' c. M
5 R, A; p: g* @) O" v  ~/ o0 }9 R程序代码: # |0 m' y% A# \* p

/ b7 x9 a! d5 q. Y0 F: S3 Dnamespace fy_Exp{' ?  D- q! h) d% j* J* g
namespace {template <class _T>
! @  H2 c/ l1 Q2 K, Q( jinline _T GetExpValue(_T t[], char& csym){
1 R2 W  ]( ^5 w& k. F6 }. Y" F' Q    char c=csym; csym=0;/ w: K3 i! f/ \4 b( y
    switch(c){/ F* |8 T- J/ C5 O6 c: J7 {1 o
    case '+':return t[0] += t[1];
+ h' f& @" p& |3 Z# L" r8 d- q    case '-':return t[0] -= t[1];" q8 A- _8 n) d- R" Y' r8 l& E4 ?
    case '*':return t[0] *= t[1];
& d- t& O1 W& C9 ]    default: return t[0] /= t[1];//case '/':: I' ?: ?! x6 @& b! O# t- i, G
    }
5 J$ |$ p" Z1 F. f" ~2 d7 G% ?: j}}
0 K0 l) K9 m& G" W# l2 Etemplate <class _T, class _Tstream>3 M' Y. D1 Y  _' S, q2 ]6 `
/* _Tstream: inputstream, _T: get return value
( P" j# N+ _  ?9 ?* Return nonzero if get value successfully */; G; i% T& O' e& Y/ T% T
int GetExpValue(_Tstream& istrin, _T& nReturn){
! h' _% q, a+ W% ~; a  U0 k    _T t[3] = {0}; //雨中飞燕之作
2 _* i9 p( s) q! R. m& s    char csym[3] = "++";
7 H" S9 g$ p. A! b    int nLevel = 1, nERR = 0;, P) W) t+ |6 h' J/ u" m3 o
    if(!(istrin>>t[1]))istrin.clear();
; e$ l2 @# G- T' P8 y    for(;;){  y% n& X, H/ {7 U3 c* @, L$ P
        if(istrin>>csym[2]){" A! o: q( }7 `+ ?  @4 f- w
            switch(csym[2]){/ a) h) t# v! ?% s4 p' g
            case '(':/ y: E7 P6 |! C, M  R9 z
                if(!csym[1]){nLevel=0x100; nERR=1;}else
6 N% F9 H4 i7 P6 [# Z                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;7 X; m) e# @, k4 R
                else{nLevel=0x100; nERR=1;}
; F5 g3 C. n% D/ q                break;
0 I! p; V" s$ G9 j8 X. [            case ')':
( ^; \6 C( H" U: v2 d                {nLevel = 0x100;}break;6 h' B) V9 L, Z1 ^
            case '+':case '-':case '*':case '/':& m3 s4 `6 x% @% r) ~2 b0 W
                {csym[nLevel++] = csym[2];}break;
: k# b' r. g( N& v+ b; X/ v            case ' ':case '\r':case '\n':case '\t':continue;% T. X* W1 j6 ~$ @! L
            default:
, V# g" A  ~9 b0 G6 S                {nLevel=0x100; nERR=1;}
1 f: |$ |5 S6 u5 y# s            }) B9 c  b- L) W/ ^
            if(nLevel==0x100)break;8 D! d) \9 _3 l5 B" D
            if(nLevel&0x10 || istrin>>t[2]){7 @1 t: D7 `' X2 O2 p
                nLevel &= 0xF;
- ]2 c( a- P% V8 x% m  B                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
1 I* U. O8 T) g- R+ W5 i' d                if(csym[1]=='*'||csym[1]=='/'){
( p4 A& h+ p9 z: t                    GetExpValue(t+1, csym[1]);
' O2 v3 E; A# C/ r- g0 p                }) E/ `/ S, ^# x9 ^
                else{; B9 u& u' i# ^% h
                    GetExpValue(t, csym[0]);
/ p6 B+ X1 r# B8 _+ g* v8 Y  y% @  e                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;) E: h, }' V2 i0 s
                }9 D# h, [/ B; |* [( u( z: n
                nLevel = 1;
8 |! R, u2 n! `3 \4 T# [: F            }$ j" z8 |$ _( ~, D2 o/ k
            else istrin.clear();5 g; }8 X* v7 [0 [
        }
0 m' [* Y1 I" i& b' _        else{nERR = -1; break;}
" B. G1 _- H  O3 m    }. n' y" R* S# {( ?+ U
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
* {. D! L, \: x# u3 A; f4 \  j$ `% c    else nReturn=GetExpValue(t, csym[0]);
( m6 Q: a" c, ?  z) _. h    return nERR==-1?1:0;
  N9 ]$ u1 i% f: s- v  O% X}}
% t& k! D5 m! G% T$ T7 g3 d" b" X3 ~, P" C  b
# x3 y! z7 e$ H( P0 k
0 g/ S5 k7 S. i9 u
函数模板使用示例:
. G- b0 c9 e7 e4 X在以上那段代码的后面加上以下代码:/ h$ F3 }! q0 ]; \/ _- {+ j

8 I0 A0 t" u3 u7 b" O % K1 f3 Z9 K8 s* G, I: V

: V0 |( f  n+ T+ {3 g2 q7 f程序代码: ! s# L& Q; u0 U$ _) r* H2 g" h3 [  g
% R0 W& u8 ~" I* w2 @7 \$ D
#include<strstream>
2 H# F, ?( m0 A7 i#include<iostream>
6 v3 C  T7 R( h5 k#include<string>
& Z3 m5 i# x% T( C. s& s; \using namespace std;4 N% _, F4 U: q, [# g9 N! B2 i
int main(void). E: W% H9 J* a. ~( B% p2 |6 _
{
1 A+ o4 T; |8 e$ E. o    string s1;8 j8 z! w: }- a  f% B
    while(cin>>s1); }* P" l7 K' c7 ^- S6 y- N4 g
    {
; W3 U7 F% I4 i4 D& e        istrstream isin(s1.data());
, Z5 J& _% `" B        double d;, ?2 e! l$ \/ H9 m8 e
        if(fy_Exp::GetExpValue(isin, d))0 t! m- \% x, G  X) j
        {
2 o# z; |( L& A% S7 u, E4 Y- z0 h) e            cout<<d<<endl;0 C4 S' g# N# x) W6 i" n: q
        }
5 g: V- e: U0 e+ P        else5 }# @" ], Z, n4 n' M2 ?
        {
! o  T# x9 t1 c* q4 n- v            cout<<"ERROR"<<endl;  A* E+ V1 a* I" H# c6 I, F
        }1 E1 n% R5 o& Q# ?( n
    }
1 q* H1 k( _+ {- ~/ p, c; }    return 0;, n! V$ ]$ b0 y
}
0 h4 A5 M. n( b5 {) k# J+ B7 e2 q  ^' ?
4 `& f. t$ m) q6 {: Y/ X: Y) `5 W
然后编译执行就可以了(*^_^*)
, Z( b" ?  Q0 ~3 O其它:TC++上一定编译错误,不保证在VC6上也能通过编译8 l$ M0 [0 t: L  z3 f& P
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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