返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
' K* b. N3 y% Q6 l! F+ h# n一个很方便的函数模板,可以并且只可以计算含括号的四则表达式) }$ \) ^; r: X8 q6 G: q* b
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
  E; t7 z6 k# }. U; D' \0 g+ w参数解释:: }* y$ x2 u$ O7 \8 b+ O9 L4 j
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流! X0 Y) ]* t+ L+ L# n4 q' H( w
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
( m$ P" F4 ]" o2 H; b% u返回值:2 A/ m2 Q( d9 b  L, W3 c, r! z  d
返回非0表示计算成功,0表示计算失败有错误
1 k: G) J# s6 [+ |& S0 ?
9 R* S3 l' d3 X
2 ?# p7 }: ]9 B
5 w, l, `# j& K  u9 I# l程序代码:
2 i) r" D% L( ?; c( X. {) k: f; K4 J
namespace fy_Exp{
. M5 @) P3 o5 {namespace {template <class _T>
9 T0 c# s; X7 i/ k) M; N# Xinline _T GetExpValue(_T t[], char& csym){
+ C5 Z3 N$ j* A: u    char c=csym; csym=0;
" G# C$ S3 z) B- M/ t1 g/ C$ ]    switch(c){7 z5 ~/ K1 K% f6 k3 {; }3 J0 w; {
    case '+':return t[0] += t[1];
6 f5 C; I' ^. {0 x' g3 o    case '-':return t[0] -= t[1];( ]1 A' S! Y) `" a; z) F& z0 L
    case '*':return t[0] *= t[1];* @( e, Q* O; _% }% v
    default: return t[0] /= t[1];//case '/':2 C1 Q/ m3 s0 y6 P6 H4 O
    }1 t; U1 E" Y! E) d. g
}}! E$ r( i! R7 i+ t* R; n  J& i
template <class _T, class _Tstream>
+ T( z+ b& {- ]/ T. R/ k5 A/* _Tstream: inputstream, _T: get return value8 g" }% P" g* G& G8 K
* Return nonzero if get value successfully */
  j! X# x7 {0 a# wint GetExpValue(_Tstream& istrin, _T& nReturn){$ @9 \  v3 a6 K& v) K+ Q
    _T t[3] = {0}; //雨中飞燕之作2 C( a' W. u* m; `! r/ @5 u# c
    char csym[3] = "++";
  X$ n* Q8 g) f5 d% F, ^    int nLevel = 1, nERR = 0;
6 p6 i, H! b$ \* |6 v* ~+ A$ I    if(!(istrin>>t[1]))istrin.clear();6 W( [, h+ E( z! i% g
    for(;;){
+ A8 `0 N3 |3 [. K" m8 h% J8 D, H% r        if(istrin>>csym[2]){
. W8 i; e5 P/ l) O. |% b            switch(csym[2]){
7 d7 @$ L3 o$ v            case '(':2 x; ~' t* Y8 w  P5 P* \/ `- f
                if(!csym[1]){nLevel=0x100; nERR=1;}else: d! G4 w% `: m+ N( r6 B" V
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;, ^+ W$ V( C* }0 |& W1 a2 K
                else{nLevel=0x100; nERR=1;}
$ V. l* L- m6 ?' d                break;
" Y( U$ c1 U5 O0 I9 R            case ')':
) T+ p4 W+ [- z' E7 w& X+ c                {nLevel = 0x100;}break;
  N: `+ [3 ]% S3 n: |8 q0 I            case '+':case '-':case '*':case '/':
( k  s, d$ N$ }& ~1 u  G, x* r                {csym[nLevel++] = csym[2];}break;
' c" d$ G. P* O8 Q2 _- b; f7 P            case ' ':case '\r':case '\n':case '\t':continue;
# J! {" U9 y" L, W% r            default:
) h6 E3 u8 T: ?/ H% K& t" Q# B                {nLevel=0x100; nERR=1;}* Y4 l# h! I7 v$ C  D
            }; {9 ]1 e+ M$ S
            if(nLevel==0x100)break;
5 [3 ^; d6 v# s" Y            if(nLevel&0x10 || istrin>>t[2]){3 w+ I  v9 u4 K2 C% H, }: M2 e
                nLevel &= 0xF;& Q! R0 m0 W& H1 e# c' f
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}- ]8 d+ P9 c, Q/ S! {
                if(csym[1]=='*'||csym[1]=='/'){
; s* V) ^) w# `3 L                    GetExpValue(t+1, csym[1]);: I6 d# @, b+ n
                }
! y% ?1 w) J) n& [+ h                else{! C5 q2 {2 O! }$ N
                    GetExpValue(t, csym[0]);1 O6 P) y2 t* t# j4 @+ z  O3 S
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
2 z! S5 H0 M. P0 z1 _                }$ U$ T3 b) p8 r5 E
                nLevel = 1;7 C1 o9 I" W5 _' o/ A
            }
! c" q1 A, q1 W- {            else istrin.clear();
& v1 c. U2 Q4 T0 E+ X( t) ?3 m$ B        }
  p' `2 C& i0 }5 _" }* S! E) G$ \# C! Z        else{nERR = -1; break;}
$ l$ N. _, h" W9 j  Q8 ?6 X    }* Y1 V6 [" Z. A" J! ]7 y
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);" `9 V' f2 w' x6 g
    else nReturn=GetExpValue(t, csym[0]);
8 i# Q6 B- c; Q    return nERR==-1?1:0;
, {7 h  o3 O' A( D+ J}}
' v9 M1 E2 m! l# Z$ K/ W+ D- ?- ^4 f. f9 M# n- ^
/ M6 B* h: H2 e" f5 i6 p1 `
& b7 H# ^% a4 F. ?6 F/ W
函数模板使用示例:) w" }' x; J) |7 F1 s1 y  e
在以上那段代码的后面加上以下代码:6 Y1 Q6 w: w! W9 |9 I1 {& I

8 p0 x/ [6 M4 d) W4 e/ z1 ~: k * W" }# j. P  q- _8 f
& \% P+ s3 q) m! h
程序代码:
2 W0 p* R  u, q% H! O2 u; M* s# I  m: }% `4 F- |
#include<strstream>
  h/ o; M; |- o* N% E: m#include<iostream>
, b5 h" t  f4 k3 B- F#include<string>
# p; D2 j+ o0 ?$ s- Susing namespace std;! l3 R% g+ N: w' ~  z
int main(void). G6 {1 X5 I% l2 G, N: g8 d
{+ q  z4 H# |+ m
    string s1;
8 X# N6 M+ B  w    while(cin>>s1)
3 w+ C# _7 h) G; M/ C    {( c7 f  `0 ^9 ?: x7 ~# H& L5 B0 h5 ]
        istrstream isin(s1.data());2 }1 K/ M# F7 T8 t
        double d;
+ z$ v+ |, z9 ~        if(fy_Exp::GetExpValue(isin, d))
8 @# N7 A: a6 x2 z' B$ d        {
7 }$ Q1 ]% H# z/ V" I! D( x            cout<<d<<endl;
0 P& Q2 T2 w- Z1 ?5 e4 z1 i+ w        }$ r# y8 H7 K* u6 }0 V# D
        else
) }$ y  j7 E+ H/ E8 H        {. t9 N3 j2 f, g% f, `9 @2 c$ Y, [& M
            cout<<"ERROR"<<endl;0 {5 U( l5 F% l7 X& m( S; m( [
        }/ [: k4 T  P3 c% \1 {* V
    }9 L6 L) w6 Z6 b9 i$ K7 o, c! ^
    return 0;
. Q4 I% u8 R/ w1 Q$ k6 z7 O}
9 H; N" p% e9 Z# s
( L: T# V/ r4 I' ^/ Q9 O  {) f: n9 ^9 E. l0 o4 R
然后编译执行就可以了(*^_^*)* s' b1 V6 B3 [: V
其它:TC++上一定编译错误,不保证在VC6上也能通过编译
5 ~8 J9 p6 Y: \" }  Y" [) ^      建议使用VC7或VC更高版本,或者使用GNU C++编译

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