返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,1 ]* _  w2 |3 i' g3 Z* W
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式' H6 }7 ^$ |# m& R
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
9 b/ r* k3 ~8 d. I6 p* j/ v参数解释:5 v3 U2 i& r& o% e: ~$ |3 ~9 Q
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
" \3 e9 P; j' G5 D4 S7 ?nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
" h6 y: p, G. n返回值:
4 s  Q: F2 G; z- L- ?3 F1 s返回非0表示计算成功,0表示计算失败有错误
! i( v, q  Q  E' h
+ N' b# `7 O& t: z3 H
4 B7 n! O9 ^( r* ?( l, a
) G: W: [7 M1 z6 Z' Y# a程序代码:
; R) S4 b) I5 {' Y, v  l* p: a5 l  M) Z5 ~; y$ v
namespace fy_Exp{( _+ u+ V: T# J0 G4 Q. f4 F
namespace {template <class _T>$ ~! v" r6 _- ^, A. R
inline _T GetExpValue(_T t[], char& csym){& ~% Z0 ~4 ^7 C( Q: g5 H: g
    char c=csym; csym=0;% G+ q. r4 `. p) k5 T) D
    switch(c){( Q! f7 m0 B) ?' r- y
    case '+':return t[0] += t[1];% S( k4 _$ c8 O) H9 J) C3 b5 _
    case '-':return t[0] -= t[1];
: N- p9 T+ |6 u2 B% Y: g    case '*':return t[0] *= t[1];+ p, q( ^6 {, y7 U
    default: return t[0] /= t[1];//case '/':
, W& C; C7 C5 E3 k$ S+ Z1 {    }
5 i: \4 D  K& q& G6 l}}) x3 g$ i3 P. _. |) I
template <class _T, class _Tstream>6 A% |% V: ?# E
/* _Tstream: inputstream, _T: get return value; F% o5 e- h4 }5 Y0 F
* Return nonzero if get value successfully */
% l% l& `$ E8 A- E7 N+ aint GetExpValue(_Tstream& istrin, _T& nReturn){
; H+ G& z" e$ m6 e4 Q% B$ O# h    _T t[3] = {0}; //雨中飞燕之作
" j2 v( U* F/ s8 ^" B    char csym[3] = "++";+ L0 S  e- L( Y
    int nLevel = 1, nERR = 0;
0 t$ K3 G2 P3 l6 ~, h    if(!(istrin>>t[1]))istrin.clear();7 v3 D7 I4 ]5 ^0 m  x6 F1 w
    for(;;){
% w9 F+ \2 t: y& Q5 [- L% n, \% [: v        if(istrin>>csym[2]){
- ~, B+ i% X5 F            switch(csym[2]){
; K8 u- a) R( F( d  U. T9 a            case '(':
' `! j, {% i( d8 y4 l8 r( m                if(!csym[1]){nLevel=0x100; nERR=1;}else
" C  I4 Z  e$ X" {& e: t+ |" s7 D8 X0 v                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;* g  n, H- V- i. t( u! K
                else{nLevel=0x100; nERR=1;}- M1 ?; X& Y6 x9 r$ J% w8 Q) N  \
                break;2 h% Q5 [6 K( A; A4 @- c. u
            case ')':; J' t8 m4 O% d+ l+ y9 ]. B+ _, ]
                {nLevel = 0x100;}break;% j8 Q' U: b' O2 v" J7 B5 x
            case '+':case '-':case '*':case '/':) [4 \# G% h9 B; p) t
                {csym[nLevel++] = csym[2];}break;/ B; i% G, O: `+ n7 j
            case ' ':case '\r':case '\n':case '\t':continue;
% c9 d4 K/ H' S4 j2 m1 i, i+ E            default:
8 z& a. t. r3 p4 y% d, D. {: i. N                {nLevel=0x100; nERR=1;}
& v  \' d  ^1 m- O            }2 _$ A5 e9 Z8 _: f4 p0 {
            if(nLevel==0x100)break;  y+ q# o4 E# b! s0 ^
            if(nLevel&0x10 || istrin>>t[2]){1 I2 J* \) ~5 {2 _% d6 y. J+ Y
                nLevel &= 0xF;- g8 `, w; i6 h6 d/ _2 ^
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
# q9 y* A; H. X5 v                if(csym[1]=='*'||csym[1]=='/'){6 S8 W+ E: s* D3 m8 A9 G
                    GetExpValue(t+1, csym[1]);7 m5 y* p! I: a. l
                }
" n: H/ B& @1 R* X; A$ h  C8 t                else{
: ^- ?: H9 F7 Y6 x                    GetExpValue(t, csym[0]);
' U' |8 G5 A! S& B+ E                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;# `! N6 b; M* c! n  O; D8 [
                }
: U  G$ V$ m, h                nLevel = 1;$ }3 u0 F& Q- k/ e% S, ]- E
            }
8 d: u7 D& ], P. Q4 n8 r            else istrin.clear();4 i, T) P9 c; \! C+ i$ a- G
        }% Y, J. p7 N9 U0 d# T
        else{nERR = -1; break;}
) w4 u# ~  L4 F2 Q; }    }& @/ }# u* }; K, ~# C% L
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
7 ~& @" Z9 M/ J+ C" r  D" \, G( W( z    else nReturn=GetExpValue(t, csym[0]);
- L! P# V3 D, B2 w" v$ n    return nERR==-1?1:0;
/ ?" M1 g3 j3 D+ i8 A, V8 w8 m- b4 I}}1 h4 j) y9 w' U! e! h& |
* ^. T: A1 @' u/ t: L1 Z' Z9 D  _

( `' t1 w; {8 R- Q6 `) m  A; z+ r- u3 U) F' Q. b
函数模板使用示例:8 n$ n1 d" J0 i! |
在以上那段代码的后面加上以下代码:  c4 i# L6 c. [6 Q; x  x; P3 c4 L

" [' h/ i9 ~8 i# a/ B1 l ; D4 ~( n- s; w) \

- @$ R/ a2 h% D" X程序代码:
' P9 Q" s  u$ X% {. f! F, k: Y. C2 P9 s/ k6 s2 A/ m' Y; c* P9 n
#include<strstream>, d7 \5 [% d2 s: ?
#include<iostream># l3 g, e2 k5 k) t3 x
#include<string>* d& V7 h$ _8 Z
using namespace std;  F2 j/ H" q8 J, x# H5 z
int main(void)
8 B, {" B6 _& O' ~4 u7 v% `{4 Y$ T+ v. n) B
    string s1;- i" G* t" y( E5 n9 J. x4 F* i+ |
    while(cin>>s1)2 l) x- Q, [( g) O; v( U# P" W" W
    {
" {* a7 `, N' n( ?9 O        istrstream isin(s1.data());
; W: [* w* w& k! U- q7 ~        double d;7 E! P& b2 v# t1 l# q( s5 Z( g8 S: p
        if(fy_Exp::GetExpValue(isin, d)), |: ]* ^1 f+ o" E4 \& n% ~, l
        {
& X; j( q; m6 d            cout<<d<<endl;: B7 u( i9 X$ m/ A2 C+ {8 W
        }# T6 S5 W+ e$ w" l" a) G. C
        else
; B9 X2 y$ z( n! h% z; m        {* G7 ^4 e3 P* `! M  b3 @
            cout<<"ERROR"<<endl;
$ J( j, K# |" e  D/ [9 n7 o8 ^        }. o# F8 C* e% u3 {6 B( S. n( Y5 P
    }
! c& D6 O6 J3 C, M0 t/ V  z    return 0;+ l* J0 H6 i1 D$ U# L) t$ }2 Q- y/ _
}$ X/ M+ {* S9 P  I) r8 D
; V9 t! B/ C% h, @

3 P, y% t7 h- v$ t- `然后编译执行就可以了(*^_^*); E- b% B, d4 T  O6 o; V
其它:TC++上一定编译错误,不保证在VC6上也能通过编译
' b9 b) R& k' m' L( @      建议使用VC7或VC更高版本,或者使用GNU C++编译

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