返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
* k" k/ H4 s4 s4 o( n  T2 H5 \4 ]一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
, l" }  h! W, {' _+ H7 t只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn); B- ^- `7 B+ k1 R
参数解释:
( L6 |$ _- D) D7 x/ D2 `/ C! H4 w; e6 ]istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流) C! X, f' ~1 Y$ R" Y; w
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定) K9 z2 n3 d6 _: f2 d  I  g
返回值:
6 _( e) }6 J6 Y, i9 o; b# @返回非0表示计算成功,0表示计算失败有错误
+ L, P: }  [  j7 T' B) o
) D6 h! F1 ^5 h6 b+ ^( b4 _% ~
  m, v. m. A# F% a& p6 R2 j5 E2 [$ Y! l
程序代码: / j2 W5 e, h* v2 c: Q2 x# U

  ^5 g7 R) S4 A4 lnamespace fy_Exp{( d0 o" {  H7 a7 q( `  m
namespace {template <class _T>: K6 n1 D' h3 p
inline _T GetExpValue(_T t[], char& csym){1 ^9 W4 F0 \3 ^; t
    char c=csym; csym=0;! {& q& n. S9 L  V  K' h: G; {5 o
    switch(c){' t8 V" D& v2 O4 P! {2 H& e
    case '+':return t[0] += t[1];
  k$ P1 R2 H3 x7 H- l    case '-':return t[0] -= t[1];
# \) v5 C9 w. H" I# m2 j    case '*':return t[0] *= t[1];
+ Y3 C8 Z/ T3 G; b; ]2 q) j$ e  L2 x    default: return t[0] /= t[1];//case '/':) m+ x5 m! r6 e. t: X+ g" \
    }
5 x3 E( v7 d( l; p}}! t" U/ L9 _6 ?* i5 [- ?
template <class _T, class _Tstream>
* ?. y' e% O  h  `/ o5 _# G/* _Tstream: inputstream, _T: get return value" P' A+ v3 T. v9 N- q  L- P6 l) [: d9 X
* Return nonzero if get value successfully */0 `) E: ^; t+ Q9 r+ x
int GetExpValue(_Tstream& istrin, _T& nReturn){
* I2 Z# B' i9 J( T) _3 E! x% y2 W    _T t[3] = {0}; //雨中飞燕之作
) C+ j% D2 ]* i$ [+ a* {6 r    char csym[3] = "++";
5 p; N0 Q- e% r    int nLevel = 1, nERR = 0;
: J% Z5 E1 W% u) \  ]    if(!(istrin>>t[1]))istrin.clear();
6 d. K1 a+ g1 I" T) E, n0 x    for(;;){
: l% v2 o+ c6 i) ~9 e$ ]7 I- {$ t        if(istrin>>csym[2]){
! ?* [* _, }& y1 r            switch(csym[2]){
2 ~/ A& f2 }$ C" H, u+ V            case '(':! L% P* U1 o$ l
                if(!csym[1]){nLevel=0x100; nERR=1;}else' s7 e. t0 Y8 @) W" ]# d# C
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;; S  ]: q4 z3 @/ ~7 q
                else{nLevel=0x100; nERR=1;}
. J0 y' W7 Q- b$ e+ ]8 Y                break;
/ \& r0 ?( a4 Y3 [            case ')':, h( E% i: v; u# |/ O  c
                {nLevel = 0x100;}break;
% l: x  E6 k$ T            case '+':case '-':case '*':case '/':! e  w- b9 _% b% {+ ^$ m* j1 ^
                {csym[nLevel++] = csym[2];}break;& y7 _; ?# f: s- [: t9 L
            case ' ':case '\r':case '\n':case '\t':continue;
2 r( W0 q0 X5 [8 G, b8 v            default:
6 R" f) }! b- ~0 S" {2 Y$ v                {nLevel=0x100; nERR=1;}) ]. R1 Z- A, ]% s$ h& A
            }1 \8 d  C0 \1 E) g, o6 j; N0 M
            if(nLevel==0x100)break;" N: x4 b8 p5 ~
            if(nLevel&0x10 || istrin>>t[2]){
/ |; [% u' Q( Y3 D& k6 V' {                nLevel &= 0xF;
( }+ e7 |% F5 S: t- Z                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
$ e* P" C9 C/ _9 N                if(csym[1]=='*'||csym[1]=='/'){
; G1 \6 o4 q* X% y                    GetExpValue(t+1, csym[1]);
/ s! D6 u% P3 G' X( B                }, p2 s* S: M; B8 C
                else{& h3 ~7 D1 q  ^+ c# F5 o# \
                    GetExpValue(t, csym[0]);
( J% L% b9 d8 R2 q" P" r2 e                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;$ M1 l9 r# _. W% h3 \
                }: _/ Y9 @* Z6 l2 |" k) \
                nLevel = 1;4 V% o. [+ P" t6 c
            }0 u5 j7 e9 ]6 o/ Y% T# l% E1 Z8 N, x
            else istrin.clear();) i1 Y/ m) p( [0 K' |
        }' `! A# `8 o# V6 R, i7 Z
        else{nERR = -1; break;}
) ^' T0 K7 `6 ?; `2 ~- h    }% a6 {" u& K% z1 R, w3 m- U
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
- B, Q7 I2 m% }9 h) p3 O    else nReturn=GetExpValue(t, csym[0]);) C6 U5 U# v- ~! O3 p
    return nERR==-1?1:0;( u% N1 b- G, y3 ^, W
}}
/ {1 s% N3 A0 u- W  H. o
" }! ^5 a5 e  N4 W% l# D6 y4 \" c8 F$ z; b) M( z
( c' m% [" Q9 }
函数模板使用示例:
2 I# J+ M) S  m, V: k- A2 q在以上那段代码的后面加上以下代码:& z' Z3 i* q: e9 }

5 R6 w" v4 w( X2 Y' S! A 0 g8 {; y+ E: d
  t! e' Z: Y8 G/ q- x  ?* E5 q
程序代码:
; ?3 c" w, G/ |) ^' r: H4 v
3 a# L0 a5 E6 P4 W/ H#include<strstream>
# J9 n0 f. r2 M( e% ?0 E* k) n#include<iostream>" }( y  Z9 @! z& |- l$ G. @7 n
#include<string>6 C. r5 y# g$ ?# D, D- w/ I
using namespace std;
& B9 }( d% S9 S6 vint main(void)+ R; Q5 ^: q9 p! u  T7 L/ ?6 [
{
3 D% F  i4 T% e" b/ I    string s1;
* A  r- g, l+ U! Z* C    while(cin>>s1)2 Y  X  I. q8 G
    {
' `4 P' F! w* H        istrstream isin(s1.data());
6 K! u; G7 B, h: I& q        double d;3 Y5 d6 M  |2 A, M5 _' s# I; C6 k
        if(fy_Exp::GetExpValue(isin, d))$ C) ?$ y% H/ D2 {
        {: P) Y! g' E2 j4 v3 i$ o- H% }
            cout<<d<<endl;
4 c/ y3 `! \. I! X. T1 _; M% U( ?6 d$ o        }
9 K) _$ K/ D$ N/ b; ]2 g        else+ Z5 F8 U0 }' M6 ]
        {
' q& `# S: [4 `7 j- Y  g$ h            cout<<"ERROR"<<endl;
- O, l. r2 ~2 Q        }8 Q6 e& ~9 w  a8 ?( U. U4 k5 A
    }2 T, m. u+ p$ `
    return 0;
- o, N$ o" w; g+ L: w1 C6 X}
# |* c! ~% l) W, B: a8 y7 M
# _+ T! n% @( `& y3 @6 ?5 Y$ d- m, I1 W5 L
然后编译执行就可以了(*^_^*)% [  R! O7 w' g7 D
其它:TC++上一定编译错误,不保证在VC6上也能通过编译2 ~# P0 C& a. v* ]0 f- \9 Y
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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