返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
, H$ t2 D# a, V) L% e) ^1 g一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
1 X4 t0 ]" B6 K  V8 w- P, U' G  `只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
: b! q1 C+ {" H* W' @  ~8 T参数解释:
3 }3 J, y, [% o5 e- y4 L5 w& f& yistrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
# U& v% f/ E5 J6 I( h- \- znReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
4 F& d9 s% o* ~5 P8 |返回值:; d2 }1 h( ?6 Y" ^1 L5 J8 T( L5 N1 v
返回非0表示计算成功,0表示计算失败有错误+ Y" N$ ?# W! y# I  H
$ c' R2 s: [9 t3 h8 l" y

/ Q1 P9 R/ h4 u0 T0 O9 B, G
3 \( ^7 M" e+ m/ \9 W5 Q程序代码: ' C2 g; a, e) x* t6 d  L6 V* w

4 g9 \0 `6 J& g3 s5 u  ynamespace fy_Exp{2 M! ~9 ^1 r5 x6 W: T
namespace {template <class _T>6 u2 G! P# ?# G/ I
inline _T GetExpValue(_T t[], char& csym){
6 {5 y( V" a1 l- O* R    char c=csym; csym=0;
" l! z4 J( v3 j  X+ ^- p6 `" f2 a! ?/ H    switch(c){5 ?/ b, d& n$ C$ Z
    case '+':return t[0] += t[1];+ S0 h  K+ F9 R( A
    case '-':return t[0] -= t[1];0 ^; e  C+ O; {4 z
    case '*':return t[0] *= t[1];
% w0 y- E  W0 F    default: return t[0] /= t[1];//case '/':
9 x7 K( Q" Z. B, n1 G    }
' F1 H' ]# ?. p: ~9 z4 x}}
; @) e6 p  \- dtemplate <class _T, class _Tstream>- d6 q! M" Y: f8 \; L! |# F* B
/* _Tstream: inputstream, _T: get return value" `( L& e" @# U
* Return nonzero if get value successfully */2 ?5 j- W9 ]1 _7 T
int GetExpValue(_Tstream& istrin, _T& nReturn){* ~( s; `+ s8 K- X. [, U$ r
    _T t[3] = {0}; //雨中飞燕之作8 u2 i- U, N  c1 j
    char csym[3] = "++";
! ]. c& u! w, W# Q2 h# G4 ^9 w    int nLevel = 1, nERR = 0;8 N9 S+ l  ?$ {
    if(!(istrin>>t[1]))istrin.clear();
1 Y9 U7 K2 z# t; P    for(;;){+ i! J/ x" ^1 I% a3 I1 j
        if(istrin>>csym[2]){
9 x+ S, h. p+ d$ E            switch(csym[2]){  T% N2 W6 Q! h) _1 B4 X, r
            case '(':( Q, R# p! T2 T1 i: J4 N
                if(!csym[1]){nLevel=0x100; nERR=1;}else
; ?+ P4 w! ~5 t( ]                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;5 a! Z2 o  w4 Z8 X8 E
                else{nLevel=0x100; nERR=1;}# A8 t) m" _7 o$ F1 s) J- y/ z
                break;, r; h- \1 r1 T# S2 P( ?% S
            case ')':* h% Y% A- r: X( A( B( A
                {nLevel = 0x100;}break;% R4 n; y  }8 f1 {/ H" n; Q
            case '+':case '-':case '*':case '/':
! v7 F* X! H! I$ o6 p$ i                {csym[nLevel++] = csym[2];}break;
. R5 h- O0 _3 a4 x- ]            case ' ':case '\r':case '\n':case '\t':continue;
, P  S2 v. p% Y& R            default:! c+ C+ v8 d) k, P5 ~4 T
                {nLevel=0x100; nERR=1;}7 G) e8 Z" E' A- a6 U! L% R3 B
            }
) d2 G- f3 ~# a            if(nLevel==0x100)break;
- T/ g9 q, `, O            if(nLevel&0x10 || istrin>>t[2]){% _- P, g- b( `0 y' d
                nLevel &= 0xF;
2 |5 R, x. }* p# U                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}: h. [# {' _0 `# U4 B( q7 y
                if(csym[1]=='*'||csym[1]=='/'){3 O$ }; Q2 `5 U- r5 k; a4 u
                    GetExpValue(t+1, csym[1]);8 l2 S8 W( ~& ^: j1 q9 J
                }
6 H5 H. ~9 i6 C: q+ L                else{+ b8 B/ Q7 D' h! E9 z' m
                    GetExpValue(t, csym[0]);; B/ [9 R- k4 m5 j0 X
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
3 G3 s+ o( h$ ~4 y                }6 F. F' b6 v$ z9 ]8 ?4 L# E
                nLevel = 1;
/ g+ s  d9 R! ?* w# m5 E. F8 b            }. E& G5 x. w$ e7 {$ ?2 ]) }
            else istrin.clear();
4 Q1 b5 q4 t0 B* N2 n8 H3 g        }, r+ k( B1 C) z1 x7 p- ^
        else{nERR = -1; break;}
0 j% U9 L. \4 \    }
1 ^9 B8 o" B  A4 `1 l: Y7 |0 y    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
; \- Q' M2 h3 c$ Q    else nReturn=GetExpValue(t, csym[0]);
5 H$ M) H) g' G# s+ J( B6 Q3 Q    return nERR==-1?1:0;7 y6 H; g, T3 `1 b* R. B' G
}}
% t$ L" Q0 w6 r  N: n$ l# o4 h
+ \3 D) D: w) s3 R& [: F1 X/ E' L6 t) H5 K, U

! }6 j6 M1 [* c. u. U函数模板使用示例:- b" K1 c/ e& ~2 Y
在以上那段代码的后面加上以下代码:2 m+ e: m- R: x/ z( Q) o) \
( B4 R# V4 C- V- s

% s: g7 G0 j2 \% D. X# a; M3 {( x
程序代码:
6 p" B* ]$ `- f0 V7 f7 T7 ]+ m' X# w' y% I! @) G6 }- J( R" v, B
#include<strstream>5 {: ~0 k9 Z" E8 j  b9 O+ f- }
#include<iostream>
0 ~& r$ }( k) ~* H! o. G/ b; k#include<string>
& @, U, B5 e- Y) t- |using namespace std;
0 H0 t; x- Q% l/ Mint main(void)
' ]. B4 q; {* [' n, S/ [{1 S9 ?* ~7 e9 ~$ c* a" ?3 M
    string s1;
2 g8 B0 X% a) f1 G* N/ x- O4 W8 @    while(cin>>s1)
. A2 m' {9 a7 _! S" o    {
3 q* L8 X; ]' z2 F* E, ]6 ?        istrstream isin(s1.data());# A" _. K  M) i  I- C0 m
        double d;
3 q0 h+ ~, W; E6 m, b        if(fy_Exp::GetExpValue(isin, d))
; L1 R  t& @& F0 G        {
4 t5 S5 o: R! ?3 ?            cout<<d<<endl;% f7 w- y" Q3 |5 g- }$ {
        }6 ~; S$ q! m% P0 s0 w; L
        else
7 [7 a- V( \3 U0 H  C5 `        {: T% \: [) Y/ q
            cout<<"ERROR"<<endl;
% @! G+ b  ^; z) p! s9 \1 ~0 l3 Q        }) f8 Z+ }: ?  e( {$ b0 l: ?
    }
" K$ d6 P2 m$ z. u; k    return 0;& f( @; G1 n. Z% V3 S( Y1 A; K. ~
}- m# _+ o/ i5 C
. o) [  z3 c" n" ?- _

1 n* z% m' ~0 M$ J) n2 o1 |然后编译执行就可以了(*^_^*)% K9 K+ |3 ?5 ~, A( Z! ?! T- c0 l7 v
其它:TC++上一定编译错误,不保证在VC6上也能通过编译- \0 a" J/ s' s$ ]9 a' r; B
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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