返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
# J! J1 J& C) t9 p# G+ C一个很方便的函数模板,可以并且只可以计算含括号的四则表达式/ R2 P. y5 {( V" K" o
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
$ _8 ^8 F- d4 h参数解释:- V6 o" L8 B. b4 O. [+ A
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
7 W6 _: ~. w  U& y8 N  @nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
  V' D9 U" L+ n6 Z返回值:
' \! Z4 E# a: G. h2 o2 ^. J9 F5 N0 x返回非0表示计算成功,0表示计算失败有错误
& ?- \2 V, r- u% y2 ^8 n% K9 ^4 z8 v/ |$ t

7 e! b& w3 h- Z4 E5 J0 |9 h, S0 d  q2 D  a) V: {% \
程序代码:
& h& h1 i9 }# B# s% {) m# o1 j' U
! K- ?! s! F) a& P* T$ x8 Dnamespace fy_Exp{
1 b4 U4 z7 J* C% ^namespace {template <class _T>
" y0 d1 k" |8 b9 a' z3 n+ T" ~inline _T GetExpValue(_T t[], char& csym){" u* p% m0 @. K+ a
    char c=csym; csym=0;; u+ M/ `/ [2 [2 u7 }5 h
    switch(c){
& i0 s1 V+ C: C+ A' m; U    case '+':return t[0] += t[1];. g2 O2 q# k# u! J3 ^8 S# `9 W
    case '-':return t[0] -= t[1];! r% m& r5 U- y
    case '*':return t[0] *= t[1];
- }. ]; F+ r9 S3 {  I2 |7 v    default: return t[0] /= t[1];//case '/':4 j" ~( o) j( [! w4 U5 ~
    }
6 }$ x! S5 L: P$ t: ]5 F}}4 h) e% q6 `( ~, b% [/ r
template <class _T, class _Tstream>% a8 o, A' k+ U
/* _Tstream: inputstream, _T: get return value2 o* I: [' w4 q" f$ R- W
* Return nonzero if get value successfully */
8 F; d6 D& F; e( cint GetExpValue(_Tstream& istrin, _T& nReturn){
. P' A% a" f* C) t4 I    _T t[3] = {0}; //雨中飞燕之作
3 q% r9 O7 z( a/ H) K) k    char csym[3] = "++";
/ U+ S5 _) c7 m    int nLevel = 1, nERR = 0;8 a( @, z/ C" {1 Y1 m3 }9 G; D+ l" u
    if(!(istrin>>t[1]))istrin.clear();
+ R" [4 l: L: H# j    for(;;){7 e8 c! c  w$ z8 {1 M% |
        if(istrin>>csym[2]){" Z& r$ l" x3 h. m4 v
            switch(csym[2]){
( c& w7 w: n% X- N8 N9 T            case '(':" ^& P( V7 I8 O
                if(!csym[1]){nLevel=0x100; nERR=1;}else
3 M  E, y' u+ w  O                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;1 J7 |9 T$ @+ u' f, t
                else{nLevel=0x100; nERR=1;}
$ G/ _8 V' F- l# I; Y0 \. q% @                break;
; p) [6 v8 B7 ^" Y6 \            case ')':
& |3 D% }2 G7 o: {4 @8 M- r                {nLevel = 0x100;}break;6 q2 Y) f; w6 l* ?$ `5 _* b- x1 `0 J
            case '+':case '-':case '*':case '/':
- l' a4 c3 ~) p9 s+ N" T+ c                {csym[nLevel++] = csym[2];}break;
2 P, F% _+ P( R/ S" Q2 ?" O            case ' ':case '\r':case '\n':case '\t':continue;
% l( f2 L. R( F* V5 z; \. E& C; z            default:
" C* D# E7 ]. g( N* N                {nLevel=0x100; nERR=1;}
4 y) @$ p6 @3 N4 t3 J            }
& v* s  u; i# T& u/ c- N            if(nLevel==0x100)break;1 s7 Z, d# R6 p
            if(nLevel&0x10 || istrin>>t[2]){  r% G+ |2 x$ v) I
                nLevel &= 0xF;
  k, ]; y0 F& r0 X( Q7 c                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}! b. j6 V+ K. a/ E' }3 x: `* q
                if(csym[1]=='*'||csym[1]=='/'){5 V) Z0 o7 P- M
                    GetExpValue(t+1, csym[1]);
$ y- H& s  y5 m) Y# x                }
% q( T/ ]+ T; L/ O. F/ _5 j# _2 z5 e                else{# }! w* F! K. ?& F# S, s2 z/ |5 r
                    GetExpValue(t, csym[0]);' I& S8 G. B  o; [/ k9 i5 M
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
# y% m1 g3 o* ^5 L1 F4 q' o                }  e* G% _, M, g
                nLevel = 1;
! z0 l8 Q' l; B            }
* m* k- ~. G3 {2 O9 x# \. A6 @; R            else istrin.clear();9 A2 o! O. p& U
        }( ^- U& n) ~( |( D5 A
        else{nERR = -1; break;}0 G& }# {9 P% L
    }
- G4 d1 f5 _$ Q' K+ J    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
8 J5 j2 |/ c* p% T1 f    else nReturn=GetExpValue(t, csym[0]);% Q" t' B3 j' v3 K% C
    return nERR==-1?1:0;% ~0 S1 y/ Q% s) r
}}
& j( n1 b- @3 h, m: d/ `* L. m$ U2 o/ `% ~* ^) Z" ^* }
  h( w  K' F1 v( s

# y1 T* `2 K9 }* S" A3 X0 O" }函数模板使用示例:
# o% b1 `# P4 E! \# l在以上那段代码的后面加上以下代码:
# i# Y* D: B6 v4 a" q1 t9 q" Q
0 [% |- m# p3 h9 S7 Q4 ~3 {5 ~$ U
3 K! `4 N% m8 v0 N" E3 `- N5 Q2 F/ ?# [2 [  D& ^! O8 _5 T
程序代码:
) I! _% `+ p+ ~( |- F( G" W! |
#include<strstream>; |' e' S) A4 R  V0 {4 K9 Z
#include<iostream>; v- ?# O3 Z: F. Z
#include<string>
) i  d/ T$ Y- ?* ?0 G! kusing namespace std;+ Z3 ]* @- t- Q9 `$ m3 m5 @) o2 k
int main(void)
5 P1 u6 J0 G" Z. A* g/ Q{" n  X( v3 G1 N2 R5 C
    string s1;* t8 ]( c+ O; X, g; i: c5 u+ a
    while(cin>>s1)) C7 T% L* R& K) y& T, J
    {5 a' `4 p! ]. k6 A. o, }% u7 d- R
        istrstream isin(s1.data());
, K+ _) Y+ M1 T+ X5 m8 O/ G, C& n        double d;% K8 p) G+ W3 ~* L2 J
        if(fy_Exp::GetExpValue(isin, d))" c7 U; z3 \3 I5 _
        {3 C' p: G3 s1 S- _1 L
            cout<<d<<endl;
: D, a' ?0 I) v+ l* p        }& d) l& N) w9 X5 I+ d# {0 p; X
        else& s3 u4 C# `/ H: }5 M
        {
  w+ Y$ g) [/ @            cout<<"ERROR"<<endl;
' c+ z) F; G7 f% t  g* x' N        }
% g- x) n  S7 l7 u    }
, |5 ^3 X% s# Y" L8 ]6 O    return 0;  b- s; M: |3 i2 Q' M' y
}
% Y6 P  r5 I& I/ z6 u) Y' o7 o8 n- N( n- a& b0 M5 X& v# o% w

2 S. ~& q/ i3 A! f/ L然后编译执行就可以了(*^_^*)
; A) \% {6 j3 h' h6 X4 c- ?6 D其它:TC++上一定编译错误,不保证在VC6上也能通过编译$ W. [; J) h- s7 [* {
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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