返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
" W' I+ i/ k8 I% q% e一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
9 i1 R& R$ O- C只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
7 e  y0 P6 d- x+ ~0 J4 c参数解释:
2 O& Z' m0 K' q/ w; X# w% Distrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
1 {+ I+ f2 t) g- y( i. k- T0 N% QnReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
8 F" A3 y% @1 {1 l& z$ \( d3 r1 Z5 r. M返回值:
! D# }$ t& P0 W返回非0表示计算成功,0表示计算失败有错误* F. ?$ M$ K. Q" s8 S: K

: {* C1 ]. D3 q' a( J7 n $ {7 Q* o5 U# g% X

  q" [% g6 e$ I2 l: T7 P' K程序代码:
; w! J# [9 B, D" K
( |) V7 {# G1 a5 C/ I: anamespace fy_Exp{* |  ]7 |5 J* W; s) L  p% h
namespace {template <class _T>$ h9 W7 e- U8 \' M
inline _T GetExpValue(_T t[], char& csym){
2 z( W% `+ D& _( ]) m+ M+ o  b; e    char c=csym; csym=0;
7 N) _5 c  _6 O$ |( f    switch(c){
8 N+ m3 L/ E$ u4 d- D    case '+':return t[0] += t[1];2 c3 P: r9 O) e; q( q6 N: u- o
    case '-':return t[0] -= t[1];& e% K! N/ {. b2 x+ M! ^* a
    case '*':return t[0] *= t[1];
9 g7 {( b8 x, U$ f9 U" a; g    default: return t[0] /= t[1];//case '/':
# a/ E( k4 y% Z1 c0 M2 s6 [    }
5 H$ s% l4 k) B9 q+ x" V}}' w, i7 y: x" _) E4 ]. ^2 D9 S
template <class _T, class _Tstream>
) b" I" B, K5 x/* _Tstream: inputstream, _T: get return value+ h8 \8 t5 H* C
* Return nonzero if get value successfully */: f% p. |2 i* q& m8 t! b& A
int GetExpValue(_Tstream& istrin, _T& nReturn){$ q* S; l( ]* z: T
    _T t[3] = {0}; //雨中飞燕之作  D$ g- z+ _3 x1 x
    char csym[3] = "++";- f0 C! {* b8 c5 j, |/ x% G
    int nLevel = 1, nERR = 0;
3 ^) }0 m/ H5 [4 m) q; a! M    if(!(istrin>>t[1]))istrin.clear();2 n/ ~9 [  K3 O4 f0 `8 _& @
    for(;;){: j; V# o( u5 u: K6 a/ F5 c: l! f
        if(istrin>>csym[2]){0 W6 J& Q0 q' q! Q* t/ r
            switch(csym[2]){( d+ N0 @) ^) \# l9 ?
            case '(':5 [, _1 e! E/ C4 O" s: S3 C& m9 g
                if(!csym[1]){nLevel=0x100; nERR=1;}else! X7 t( S6 L* Q: P. T( b6 v$ X1 W
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;: \* t$ v8 n3 y% o- u' e
                else{nLevel=0x100; nERR=1;}; [5 T, U8 e' G- e: y
                break;
% V: F+ v( U3 n8 l( G9 L. b            case ')':# ^+ `. d! w2 d3 D
                {nLevel = 0x100;}break;3 |( K+ x5 N* R, O. R
            case '+':case '-':case '*':case '/':
- P" x) I* c5 k, e9 S                {csym[nLevel++] = csym[2];}break;
  N; W: s0 T8 h            case ' ':case '\r':case '\n':case '\t':continue;! Q  @# e* I" `4 o5 H
            default:
6 p/ W; W! O( m8 P+ |                {nLevel=0x100; nERR=1;}
( G3 y3 j4 F# B- @* Y6 i) }# @            }
0 Q$ S. m  i. Z! v+ u            if(nLevel==0x100)break;
$ K1 y' y* F. s            if(nLevel&0x10 || istrin>>t[2]){7 G- t! r  Q! D
                nLevel &= 0xF;. U/ ~! B* V) z7 G6 K
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
* i7 M1 u; H+ n+ v# g                if(csym[1]=='*'||csym[1]=='/'){
3 F4 ^4 A& U0 e8 {: K3 r7 r1 E# B                    GetExpValue(t+1, csym[1]);
' ~* O6 s7 @/ e+ \7 ~4 z- s! g) k4 N                }+ l8 }/ L$ M: ~" z  x+ x
                else{
) g( y9 n! ?, I5 v2 v5 H+ X; {- z                    GetExpValue(t, csym[0]);
" r. @# G9 @/ L6 }5 G9 Y  R                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
+ ?! Q& \* z$ V( \5 S5 I& o' {                }9 a  g9 ]) l. Y
                nLevel = 1;. O! X% k# q& i
            }
2 E" w% f1 I+ w' ^* i5 I            else istrin.clear();2 H- ?6 R5 O( [; a! }
        }
, A( Q: `* R8 x$ v        else{nERR = -1; break;}6 V" A( J) {8 a$ p6 c2 E
    }
+ J! a$ R7 z4 o9 i3 _- [    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);# {( A: Y& P4 w4 S' n
    else nReturn=GetExpValue(t, csym[0]);: z9 B5 s* V7 Q, X4 r% l
    return nERR==-1?1:0;4 j! o8 P8 [; p9 @( o7 F) L
}}1 U( X; e+ d1 g' S

6 ^1 s. d1 c! M0 L) G% B+ ]0 ?, }  b. s5 `9 V$ A4 c

5 H9 R: g# t' j' {5 K( m5 F函数模板使用示例:; R5 A0 ?/ K2 F5 s$ Z, c* v
在以上那段代码的后面加上以下代码:
) v% p8 L9 V- d/ M( |6 v3 H# Q' f  v; A; E% n& G$ g( r
, \; Q4 J5 F: B: C- X

5 _6 \# o# N- e# Z9 s程序代码: " G  b, _. @$ a( K$ x8 g

! N& G" \8 |) ]& Y! \+ i#include<strstream>5 |) e; @+ R- o& Y- @3 x. O
#include<iostream>
! R" ?/ w# p/ q, Q. o9 W) B#include<string>1 ]* v& S" N# L, X; R* ~
using namespace std;' e& ]$ n5 m2 |2 D( t
int main(void)3 h% M) t+ V4 o8 i
{
0 ~5 @+ v& v1 \: d6 U" N    string s1;
$ \1 V' B2 g  t4 @* q& C    while(cin>>s1). ]# g1 w) B4 }1 |0 d& N! V
    {$ w5 p: u) F( F4 T9 E& D
        istrstream isin(s1.data());
- b4 |# c0 u- H  U% x2 C4 ?        double d;: e/ p3 O+ q( n8 X; P3 l
        if(fy_Exp::GetExpValue(isin, d))
& Q3 {3 U) Q& _        {# f( V: Y9 G8 t/ L7 s# P6 p
            cout<<d<<endl;* D% Z6 P2 i* r
        }" J2 k: v  M' U  N  C. }
        else
- y  Z6 ^/ B( ]) ]3 J2 L3 t        {% D) z/ D0 G1 d8 D0 v
            cout<<"ERROR"<<endl;6 H6 M1 T3 E' B+ i
        }- p/ c9 i) F) E
    }; G- S/ c4 }7 u  }6 Q. w, T% _) Y
    return 0;
0 [" g" d. R* ^' V, a}+ r5 z7 E( R; C# V
+ G( p: A9 g" q) M6 v

- V' y. d* A6 o: V6 B& f3 g* ?然后编译执行就可以了(*^_^*)) V* e5 R4 b0 K1 H4 E# P
其它:TC++上一定编译错误,不保证在VC6上也能通过编译8 X% i+ G& P7 N, ?, a( b2 j
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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