返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,6 s1 A/ p" \7 l
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式1 T' d$ K0 ^7 _; Z+ _
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn); N6 v' L! A. Z$ B1 i8 A4 O1 w$ l* l
参数解释:& K8 r! K% O4 }
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
: f) ~6 D7 U2 j/ W& t3 J0 PnReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
7 K0 }2 Q# R2 r2 |7 b返回值:- d% K) @1 l/ W6 n
返回非0表示计算成功,0表示计算失败有错误4 r2 `" ~. h4 L

* h- x6 a7 Z* g7 T7 T ! N; N9 r3 p0 d6 p$ n

  w; u+ ~; x5 w" i( P: B程序代码:
2 {9 B5 b" f* ^! f. t, R2 f4 g" D0 ^0 }4 G. @0 O4 Z
namespace fy_Exp{
& @1 D2 `* E" u- Y. d7 b! V7 Cnamespace {template <class _T>
' T# Y2 a" A; I; oinline _T GetExpValue(_T t[], char& csym){
: I7 A; l% [' X- F/ @* Y/ [; D    char c=csym; csym=0;
5 x5 N( O) `( x% Y7 h    switch(c){
' _' C. D* d/ J! Y    case '+':return t[0] += t[1];! X) l' l) K# v0 h. @) {
    case '-':return t[0] -= t[1];
) r+ R( U) g- K    case '*':return t[0] *= t[1];$ V+ ~, j/ Y% B& D4 H  X
    default: return t[0] /= t[1];//case '/':
5 N& \* T0 w8 U    }- ]2 t) {0 g1 M, L0 t
}}/ j% \4 ?$ j. H5 j  L+ U
template <class _T, class _Tstream>
. J8 J4 x/ N* n1 ~0 b/* _Tstream: inputstream, _T: get return value/ y- W1 H: H* w: S# g8 S$ |
* Return nonzero if get value successfully */8 v- |  T4 U! ?$ B' K
int GetExpValue(_Tstream& istrin, _T& nReturn){( }/ a, F* J" d, |7 n
    _T t[3] = {0}; //雨中飞燕之作' k7 Z$ P: A( v9 I
    char csym[3] = "++";
7 X* W" T0 F/ t% \' C    int nLevel = 1, nERR = 0;
& |. r4 h) `* s- K2 b  T    if(!(istrin>>t[1]))istrin.clear();
6 y4 h- P; p/ ]3 W& Q- l) Q# K! c    for(;;){
! `, m3 g/ y  i( D3 Z3 j        if(istrin>>csym[2]){  V$ }+ B4 h: s7 ]# X
            switch(csym[2]){7 u0 j* b. `8 T; v/ y
            case '(':
. _5 m0 Z  Z7 F  Q  `                if(!csym[1]){nLevel=0x100; nERR=1;}else( l: ?! H# H0 F  J
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;+ q8 s% ]* D' P
                else{nLevel=0x100; nERR=1;}# }) i4 l* x6 Q% Y( }: p4 H/ z9 o
                break;
* l3 x0 C3 u  @" u. a$ V% \- ~            case ')':
7 h  ]; C& x6 e5 ~                {nLevel = 0x100;}break;8 Q$ F3 ]9 f4 J. Y/ d# t
            case '+':case '-':case '*':case '/':' K8 M3 @  p9 f" t
                {csym[nLevel++] = csym[2];}break;0 T* y, ^1 r" B8 F$ ]
            case ' ':case '\r':case '\n':case '\t':continue;
! ]3 L6 X* E& e* M+ ~( H            default:+ F' g+ z5 ^* Z6 _6 v# u2 W" ]
                {nLevel=0x100; nERR=1;}
8 I  D& t/ m, N) k8 S& _6 _            }
' C% S% p8 M1 B4 \  h            if(nLevel==0x100)break;6 X  R5 W7 Q( X4 g, Q3 y" q
            if(nLevel&0x10 || istrin>>t[2]){
1 H1 q) T( ^8 y3 f' G( V                nLevel &= 0xF;
, P2 Y: @$ T- Q3 X9 H, K                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
( p  I! h& U, `9 ~6 G                if(csym[1]=='*'||csym[1]=='/'){
  R- g  k0 y% A. i, u                    GetExpValue(t+1, csym[1]);
8 p( x& l2 I9 u1 f/ s; W/ E                }
5 F, s) i) h: }. m6 B0 P/ J* a. q7 F9 ?                else{
* d, y+ g% B& B8 l' I                    GetExpValue(t, csym[0]);0 ^- T0 v' ~& O2 C8 `3 u0 ~* f
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;0 z" c9 [- c8 c: n% A- t* m; e6 E
                }3 p9 [+ g9 E) [' M: j, i- o
                nLevel = 1;% v1 X; U% S) ?/ w! m: w% c
            }! n" `3 ^1 Y' }& y
            else istrin.clear();2 c' X0 S. w% n# Z& z% u
        }
6 _3 _  F0 @3 y" t        else{nERR = -1; break;}( x9 }1 P1 R' \% K9 |6 n) q+ v7 }
    }! \- t0 E& n/ }9 \2 _
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);( ]6 s8 A! ^6 a
    else nReturn=GetExpValue(t, csym[0]);
) `( y0 n! G$ |4 A; J    return nERR==-1?1:0;8 Y1 k0 C2 `( E1 Y# F* d/ t* }2 M
}}! `+ v5 ~+ L$ c8 F: [9 |
; h2 y, t3 s0 [% [+ Y) f, L% `4 j
! `( K. L; ]8 i! k) o8 |8 b; Z

& h' G/ n9 Q& i" y/ A1 a( c函数模板使用示例:
4 X2 x5 a4 n+ h在以上那段代码的后面加上以下代码:' o* m$ u  C/ W# P' W+ }
, g$ \  t$ j7 F

1 V  x3 l/ s7 o2 ?1 z
( R/ M2 m( ^& R- Y2 l3 Z  V8 s程序代码: / @* {  c1 a0 H

: q4 i5 Z$ U$ `! _" u+ [3 ]1 o9 k#include<strstream>- u* A# E& q5 R  x* h2 S. b
#include<iostream>1 h* n1 I+ h, w4 _% Z, L
#include<string>
8 O# h" M- c) n8 k# H5 Ousing namespace std;
; O' \* L" d; w5 o) s0 Rint main(void)
6 d. ~; Y$ d0 W0 i, M1 L7 d1 S{
! o3 m9 S( Q+ F! C+ W% Q9 L    string s1;8 s* Y" S! ?3 S. _. ^6 Y
    while(cin>>s1)
9 m2 u5 \' |' B$ i    {- G) b5 ^' I9 i3 r2 f) H  ?
        istrstream isin(s1.data());- L, b  D- V0 H: t! l  J0 V
        double d;- V1 I0 _7 W, v+ e$ G* v
        if(fy_Exp::GetExpValue(isin, d))
* ^+ V0 C. T3 Z, w  x. l        {- I2 q4 h5 u' G, x' E' P
            cout<<d<<endl;
% a$ C6 g" V- D: l" I5 ]: u, ?$ Z        }
4 l  }+ G  a7 g) D& x1 \! L        else
  W5 X; t  d8 |/ m7 C: Y/ t        {, W) B! o2 J8 F* o$ S3 ~
            cout<<"ERROR"<<endl;* Q- Q# P' x7 x  K- o- A
        }" e3 N8 A$ A3 P4 Q$ a! y1 Z6 e
    }" h  Z1 ?# }& K2 `( S# k5 o) q
    return 0;
! ?) l- t' o. v. n5 ~}
* j: A# O& v, E  t* [( @9 [
, b1 x9 h% U  X5 Q$ P6 h, L1 I1 D- y5 ?" [" M) s
然后编译执行就可以了(*^_^*)/ g9 `; l) [/ B: z0 a) w* Q
其它:TC++上一定编译错误,不保证在VC6上也能通过编译
2 u2 _$ c. o& R# U1 B2 a0 E7 ]      建议使用VC7或VC更高版本,或者使用GNU C++编译

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