返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,; X: j3 M! R) m7 ^/ z
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
/ H. K* B9 r+ ~+ _# u& X% B只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
' Y8 ^, s* L, X4 G! f; [0 N参数解释:$ r: P) \- T% w1 c
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流' P% Y! a# I% x
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
, [8 C+ p& Z6 i; w/ c/ i: {返回值:
3 F! G6 E5 o" A2 n返回非0表示计算成功,0表示计算失败有错误
, Z4 s7 ~5 F# Q- h2 j1 G, Y- E7 s! B, @2 z) X
- r0 K6 t. W$ E+ E) q2 |4 N

* R; ~% h9 `4 T7 `  U程序代码:
+ _8 c; O1 z2 n7 X2 f" N, K+ l9 O1 ^4 O6 R7 G
namespace fy_Exp{
3 e5 S3 A! e$ k' J7 [namespace {template <class _T>% y! t! m# l" f4 i/ E
inline _T GetExpValue(_T t[], char& csym){
1 ~3 E0 {: w# f, d2 Z! b    char c=csym; csym=0;
, v8 J; b5 h9 z1 }; c    switch(c){
, [' }- B3 Q* W' u  G4 d0 O7 ?# J    case '+':return t[0] += t[1];
3 \& R. b# H5 ^, f  M' f' v' E2 l    case '-':return t[0] -= t[1];
* E1 _7 U( M3 v  b8 d* P    case '*':return t[0] *= t[1];
! W: w; q2 k; e& m$ J8 q    default: return t[0] /= t[1];//case '/':
' P5 v0 Y0 V% q! O    }
2 E8 j* {/ u7 M3 r8 Z8 a0 U' r! U7 m3 y}}
8 Q$ }' |2 m4 W5 b/ f% _! T6 E3 xtemplate <class _T, class _Tstream>7 T$ I/ b& [4 g( |
/* _Tstream: inputstream, _T: get return value. `) n+ S! {9 c' y; W
* Return nonzero if get value successfully */
) A2 H1 g9 q6 C! Z3 [, nint GetExpValue(_Tstream& istrin, _T& nReturn){. H9 ]7 Z$ B/ r/ p
    _T t[3] = {0}; //雨中飞燕之作
1 Q8 r& k6 t% Y" k/ u    char csym[3] = "++";. G9 s$ Z% S7 y+ ^3 w6 @6 H
    int nLevel = 1, nERR = 0;
6 y: n' ^5 F6 p2 W    if(!(istrin>>t[1]))istrin.clear();
$ J8 m  |( ]% [7 i7 {. c, f    for(;;){
% m7 v* _1 ~0 {4 z  K        if(istrin>>csym[2]){( h: W  q* S0 W: c- u
            switch(csym[2]){/ L0 Y  U( I" j* M) ]
            case '(':2 V# M* _, E8 S0 I
                if(!csym[1]){nLevel=0x100; nERR=1;}else1 [7 X# O( T3 U  `( K5 U, _
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;7 G( ~6 s2 O3 n1 w0 w$ T7 I+ D
                else{nLevel=0x100; nERR=1;}9 u% r# O8 g! b' t
                break;
/ m% o: X( z" Y( O7 S. j            case ')':
# u3 Q' d# _/ z( J1 z, v/ q                {nLevel = 0x100;}break;. e4 g1 ], B- V! y- z. I
            case '+':case '-':case '*':case '/':
' T; x/ M# A' w/ W  \5 n" C                {csym[nLevel++] = csym[2];}break;
9 Q; V2 T- b3 M; H9 P9 x            case ' ':case '\r':case '\n':case '\t':continue;  Y8 j7 A- _( F. N1 m  }; c9 P. M
            default:
& z6 v+ o/ `" i- E0 O$ [0 H0 o" o                {nLevel=0x100; nERR=1;}
) q0 T1 |& d; X9 d" v6 c            }
& k& A$ m9 e: e# |' u' p            if(nLevel==0x100)break;
/ u  C! p( e/ H" p1 r6 g            if(nLevel&0x10 || istrin>>t[2]){, `5 h  A% x1 b7 S# t, x  R! R
                nLevel &= 0xF;
( S2 `5 _# ]' `2 I3 H( |% c                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}" @/ r0 ?  b) ]0 N
                if(csym[1]=='*'||csym[1]=='/'){
) z1 h6 |- J' b- J                    GetExpValue(t+1, csym[1]);& U7 w: l. X3 p0 |/ b2 B
                }
; z$ O* Y1 [! L7 S/ a% Y                else{
7 |9 k5 l0 n5 V0 Z6 B9 z                    GetExpValue(t, csym[0]);$ q9 ^* r. u- x; v
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
# L9 A1 Q2 C% l; z8 P/ {5 ?- c                }
, r7 j; {, q- D* j' e                nLevel = 1;. X% W, X: A0 n
            }
: i1 }2 K; S7 F            else istrin.clear();
6 c) S' X/ \: D: h# j, G        }
5 u" _% M+ Y  f  }        else{nERR = -1; break;}4 s: H5 U0 |9 ?9 H# `
    }
: c: c* Q# M" m) d3 h1 J  F    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);% H$ @. k* O' b4 e+ g* Z
    else nReturn=GetExpValue(t, csym[0]);* o0 c+ w' K2 N: c
    return nERR==-1?1:0;
6 x0 I: C2 Y! w}}
$ `9 h3 N$ |7 ?- D1 _1 Y9 c
- t2 ^% h3 q. s* b" S9 j$ f; a7 a
- A) F- B+ l# Q
7 ]& M& c/ }2 J3 k# m+ E函数模板使用示例:. X4 X! d+ Q$ S& n! g# r
在以上那段代码的后面加上以下代码:
5 _- D- s& G* p/ S4 K
3 P# U% f! L8 Z. i) Y
0 T& J( a5 t1 Y$ x. B* \, W& K# r8 Q6 z# u* `
程序代码:
; _. u2 ~1 t, N) Y" Y9 b0 I7 f$ V' k
#include<strstream>! X. g2 g5 m6 r+ I' U6 |: G
#include<iostream>. Z3 {( e6 R+ _- W8 r: e
#include<string>
% @2 [- |! l  ausing namespace std;
: f5 X1 A. V' I' r  j3 Y+ U5 Dint main(void)7 a2 `8 r1 c, z7 h4 j
{5 {3 x( X- y% P2 i4 k
    string s1;- u. c) l& b8 n# S' ]9 k
    while(cin>>s1)  D% p5 u+ v5 ^4 B6 g
    {+ O! T: y) J8 Z- M5 F
        istrstream isin(s1.data());
+ I/ l( q- L$ T" \' o: j4 z        double d;
. t. Q0 \% H4 s1 M. q        if(fy_Exp::GetExpValue(isin, d))$ s# u: ^9 H7 c$ \# ^8 U
        {
4 U- _- C  f) @5 @1 X9 n            cout<<d<<endl;0 n' K+ a/ m7 `( E
        }9 c+ n; @: R8 n8 W) [
        else0 P/ i# ]  @6 g2 _: q+ k. ~
        {- ]* m  ?) b0 T3 M
            cout<<"ERROR"<<endl;
- ], E& v# t) k9 C1 D        }
) T8 S7 ^: v8 R    }* l/ `3 B6 v3 Y
    return 0;4 U$ x3 @+ \5 M, \( C
}0 W& a2 R" Z" ^$ U3 }
3 s* }* I9 U+ {

% W  W( e$ Y  @) _- I然后编译执行就可以了(*^_^*)  G: H5 F- w+ H4 I0 U
其它:TC++上一定编译错误,不保证在VC6上也能通过编译
- ^0 R2 W9 `+ j; d+ ?      建议使用VC7或VC更高版本,或者使用GNU C++编译

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