返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
3 T2 y1 x& P* l& p一个很方便的函数模板,可以并且只可以计算含括号的四则表达式& t# s$ @+ g3 L' ~
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
+ L8 L6 J- ?" L9 I. a5 _参数解释:
# w, v  B, S# x8 m- T, R. Y1 wistrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
& r2 u" ?' B$ w0 s9 xnReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定. A- A. y3 E! v5 E7 D/ F
返回值:6 l6 q& D2 s4 r* p1 l
返回非0表示计算成功,0表示计算失败有错误0 D! ]& ^( t7 `. G

: u' q, u( W6 _% U
' E) B: |# s8 f3 X/ j6 B
; |" w5 S; W7 b! |程序代码:
  W" m; q6 A( ?, c7 O$ x$ G0 R1 C) ~2 [6 e! `+ M0 o8 `: p; Q* T
namespace fy_Exp{
6 J# A; s; _- e5 z' B. Hnamespace {template <class _T>& L0 P( |! E; F9 ?) p
inline _T GetExpValue(_T t[], char& csym){
2 @5 \9 F& |" X    char c=csym; csym=0;
3 D4 p' x$ Z, H! j/ E* F' N! T    switch(c){% n" o" b  Q1 j+ [
    case '+':return t[0] += t[1];# I' e5 `# P% M9 w4 f0 M, e1 s
    case '-':return t[0] -= t[1];- s+ O8 {; t6 m+ k+ d
    case '*':return t[0] *= t[1];+ G7 x0 N5 f( x1 {3 k' P
    default: return t[0] /= t[1];//case '/':
0 u/ \4 m' L$ I  m# @    }$ A- T3 d% v5 X, }
}}# @- h  F9 p* N5 D( X4 i
template <class _T, class _Tstream>9 W0 f$ p  g4 c5 s* U
/* _Tstream: inputstream, _T: get return value$ B5 B$ ~4 {& V) D' k  B9 @: r% l' j
* Return nonzero if get value successfully */
, r" b( l  ]4 s. c9 N) c9 `+ f$ Kint GetExpValue(_Tstream& istrin, _T& nReturn){
, F/ T: I3 x. [    _T t[3] = {0}; //雨中飞燕之作
& `) A) v4 E  |9 K- X% C    char csym[3] = "++";
5 k& H0 Q' I* U; d5 H/ t, a    int nLevel = 1, nERR = 0;: m$ V& F, J! M" o
    if(!(istrin>>t[1]))istrin.clear();
1 l. A% P4 g8 w    for(;;){
* i0 v' c! }* e) D' u! F% U0 `8 x+ k        if(istrin>>csym[2]){
& r9 I) ?* X% ?2 |- x2 u6 J: m            switch(csym[2]){3 M$ ]- Y% m' }$ p) f
            case '(':
7 d& m3 A, V- A7 g/ T+ N. L$ t                if(!csym[1]){nLevel=0x100; nERR=1;}else" E' z) h  y! N8 e
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
) D# X, h+ s- R                else{nLevel=0x100; nERR=1;}9 H9 R* t1 ~! a7 D) D# K
                break;" \/ V, @& Q$ A8 I8 {2 U' D
            case ')':
6 \' ~. O# j0 _, C" ?- ^( I: n                {nLevel = 0x100;}break;
& ]9 h7 r' Q6 c2 N  v7 F            case '+':case '-':case '*':case '/':- Y+ e0 S! Q, f6 r3 m+ A) K
                {csym[nLevel++] = csym[2];}break;2 |" e3 h$ {: ^3 [9 P& Y
            case ' ':case '\r':case '\n':case '\t':continue;& D4 q' X- ~' M/ S% n3 n" t- h' P
            default:
/ o& G& e. e1 N$ E+ [$ J                {nLevel=0x100; nERR=1;}
) e) `% {0 N  z! F9 g( S            }4 s8 X' Z% u. J; t
            if(nLevel==0x100)break;3 Z' S5 B# U. N* ^, {1 \6 Y* h; b
            if(nLevel&0x10 || istrin>>t[2]){
. E# p5 s. s' P; g# H                nLevel &= 0xF;& E, N: i' a9 H) L& a( O0 ~$ @, ]
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
8 X# v$ Z+ w/ Z4 p                if(csym[1]=='*'||csym[1]=='/'){8 p( }2 ]' P2 m, W2 V
                    GetExpValue(t+1, csym[1]);6 b/ n+ R5 v! M% M
                }
" q% F4 j" r& P8 w1 Y0 w  ?: ^                else{
6 c, q6 M4 c7 `+ y% g4 J                    GetExpValue(t, csym[0]);
' T4 t- e; @& G1 i5 {' X                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;: p& ~. ?9 P7 v' Z9 ^
                }
* H9 D7 W! K, n/ ]4 ^                nLevel = 1;
7 z  u$ c+ K8 C7 |% B6 K/ \) G            }9 z+ d* x0 v/ {( Z% J
            else istrin.clear();; L/ y/ g4 F* @; c" t# w4 J
        }
  u! }& N- o6 ?) R0 ?+ {        else{nERR = -1; break;}# E, u1 w0 d( j' P
    }* d- K, P1 |  Z' s" d3 O
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);+ i2 t% [) z7 H' @
    else nReturn=GetExpValue(t, csym[0]);
0 y( Y: {# B$ @* _    return nERR==-1?1:0;4 \+ g! d( ?6 Z6 o6 j( V- G& h- c
}}
+ y* ^: a5 B! ?7 D
2 Q; R6 k- {% q- G2 K2 S
+ ]- n4 P& g8 S" X$ ]
' K- `( ]$ m+ f; N" q$ F函数模板使用示例:9 @# [; Q. ]3 e/ _; \8 p3 @, B
在以上那段代码的后面加上以下代码:  @  X* [; j4 i3 k+ }
  N- R! }1 L) ?, C
3 B9 v4 i& v6 F3 q: Z& V; U5 J- E

6 A' D+ T5 K: G' y' h* C. q) F$ V( q4 y程序代码:
& Z' l; d5 C# S& w; ^: v
: k. a$ C$ G8 t) M7 L0 x#include<strstream>
5 r1 h; W2 _8 Q5 ]& k#include<iostream>
7 l. I+ j! {* O3 ]5 k. _! ]3 M#include<string>9 }7 Y' R$ W3 Q: @* i0 e
using namespace std;
/ Z9 l' Y* \: T. J$ o- bint main(void)
! p3 b5 j. x! t9 H$ c{7 {* v2 p3 A+ g: x) i, R3 {+ X
    string s1;
# m* x) ^9 j! ]* b5 c% y    while(cin>>s1)# c, p5 Z; ~2 G6 z, q
    {
( s: s  t* T% E  m! b' j4 f! O        istrstream isin(s1.data());
! E; r2 a3 V* g. H( o( p6 x        double d;
+ \' A. @3 F5 g2 A4 L8 T2 p/ F0 G        if(fy_Exp::GetExpValue(isin, d))& i& K$ n+ y# E# Z5 U! E1 Z9 S
        {
0 J7 L5 W# h. b( ?+ J4 J, Z            cout<<d<<endl;
9 A3 V& W9 ?- l. ~" A        }
  j% e* G0 `. G" o2 `        else! Q; O' a: X* M6 I' E6 R5 B7 \5 f
        {
# ?! `$ W  R: N0 ^9 m            cout<<"ERROR"<<endl;/ p. G8 s5 a' a6 {$ v* _
        }+ R9 A7 T" |$ L; g8 z% o
    }* C( `# @& _4 {) y" l( n- T
    return 0;
2 H/ P3 z/ X2 @4 T: ^  B( ~}
- S/ L# M% v, B. _; l
1 q% t0 ], M- l9 s4 Y4 }# Y7 p+ k! X  [4 |0 G/ [- @
然后编译执行就可以了(*^_^*)+ f  z, q. Q( H7 K+ ~( H1 `
其它:TC++上一定编译错误,不保证在VC6上也能通过编译
' v2 [; n% F8 l5 d4 H+ H      建议使用VC7或VC更高版本,或者使用GNU C++编译

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