返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,- V2 k( A0 O: _& @3 q
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式7 ~3 j) Z4 P8 l! \" B1 H
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)( w3 Y  M- R* n9 a6 @* `; D( S( K$ f
参数解释:
& ?8 m7 J! k) _. g; w; q$ L5 Tistrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
" D$ R6 r: P. U7 D- ~3 B, Y$ ^0 [, M$ snReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
. {/ T% V- `2 d返回值:
- ?8 T; ?  r# t5 }返回非0表示计算成功,0表示计算失败有错误
. L& V9 Q. D1 H# r! F! @- g6 q3 Y, k5 C: }; _. u

5 [7 l$ {! [/ e7 _4 |3 K5 T
' p) M1 `  M8 e" Z# `  I程序代码: , D0 t' f$ B' f1 }2 ]

9 `+ P% n& `( T2 e6 X7 Unamespace fy_Exp{
9 B  w6 p* t- ^+ b1 j3 Tnamespace {template <class _T>
% F  z) \# G, @: @inline _T GetExpValue(_T t[], char& csym){
, F5 z  D. ]1 B9 j3 c+ q1 P, ?    char c=csym; csym=0;
# h& U9 ^# Q! g. T0 ?    switch(c){% q) b7 k( @& M! j1 N
    case '+':return t[0] += t[1];
( v& l+ _/ Q1 `. j, f8 z2 O    case '-':return t[0] -= t[1];- e$ R5 L) v. U) }! y" r8 q
    case '*':return t[0] *= t[1];$ M% e6 X5 u9 e
    default: return t[0] /= t[1];//case '/':
2 l$ ?- b1 C. s    }8 e- L+ ?0 w7 t1 Z% ^3 n
}}
1 v, H9 B+ [* K& x1 s  `/ p3 ]template <class _T, class _Tstream>
, f4 u; I* @( c+ F: `/* _Tstream: inputstream, _T: get return value; v" e) y2 Q6 f* x5 v
* Return nonzero if get value successfully */
# @+ q$ G0 y5 M, V8 X& N0 v8 f1 A) xint GetExpValue(_Tstream& istrin, _T& nReturn){
' S! B4 B% p( z# o1 c    _T t[3] = {0}; //雨中飞燕之作5 J6 [  g4 _: R' p
    char csym[3] = "++";/ K" Y. Y/ }6 w: w( M5 i& {
    int nLevel = 1, nERR = 0;
2 k* O- G: Q/ {  K  G    if(!(istrin>>t[1]))istrin.clear();$ M9 T# d  c- \! N
    for(;;){
1 R& G6 v" O7 {" J. f- M        if(istrin>>csym[2]){
. q  H- a* |# g+ p& ~1 q            switch(csym[2]){
8 W6 k! t! C1 H' }6 ]% I            case '(':
7 d. @" x: x/ D5 Q3 I                if(!csym[1]){nLevel=0x100; nERR=1;}else- Y6 L" g7 c7 @! z
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;9 Z4 l, M, Z# J) p2 Y) K
                else{nLevel=0x100; nERR=1;}- |' u6 p! y) R' x0 I* a
                break;
$ Y2 J( p9 r0 V0 c. q7 o( s! E            case ')':
9 R; D1 q9 \& s0 {, p                {nLevel = 0x100;}break;
, P  n. e5 ?& H# {  G            case '+':case '-':case '*':case '/':! i2 C& @* O( r  P, k
                {csym[nLevel++] = csym[2];}break;
+ Q8 z6 m) G2 i! o& w4 \% _) d            case ' ':case '\r':case '\n':case '\t':continue;. @1 T. S: w7 E$ `$ L4 @
            default:
& g; T/ |5 M* i& d2 a: k                {nLevel=0x100; nERR=1;}5 J# c  C# {( F  `: Q9 B1 _& D4 U  ]
            }
1 ]# a8 v" `' y! L- s; b- i2 x            if(nLevel==0x100)break;1 H: c: e  U- J# X2 Y
            if(nLevel&0x10 || istrin>>t[2]){4 x( j$ w: G% P: Q# G/ r# C5 I
                nLevel &= 0xF;
$ |9 C5 v5 F4 l7 ^; ?# N7 g# I: J7 q                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
  `4 k' T# |: C                if(csym[1]=='*'||csym[1]=='/'){
: Y+ J& I1 C2 w7 Q1 o- [                    GetExpValue(t+1, csym[1]);2 [0 ^" h$ b$ @0 y! ?7 e: P
                }
7 V) g6 |4 Q# O& g# P                else{2 O; T! D" B5 T1 [- O, t4 h& F
                    GetExpValue(t, csym[0]);
, N' T% F( U' l4 E' q3 {                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;: T) V* ]: E" p" U! W; X- I. `- a4 W
                }
: A3 [! \" {3 d( X7 ]                nLevel = 1;
# w) e: [: T/ E) [            }/ R. E# b0 h$ c
            else istrin.clear();
3 H4 H) |2 b- y, K1 N        }/ i, u8 K! o$ H: r8 U
        else{nERR = -1; break;}
4 a& p5 C# [% P) i5 b    }
- U9 {  ?! N, h  Q! _& y- M    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);3 ?% v6 M' ^% H* d2 V
    else nReturn=GetExpValue(t, csym[0]);
+ o/ L6 V; r, ~. ?: t" ?/ p2 b! z( x5 |' C    return nERR==-1?1:0;
- Y' Q0 a& ?1 H( r; y}}% [1 F6 `* M7 [; c& F
+ X( _8 V( Q& t0 n0 r+ [* g% h& \- @' c

) k8 H% l( W! A& Q7 z/ ?
6 \# W. D: D4 S! \函数模板使用示例:
& _; ]7 o- O. @! g. c在以上那段代码的后面加上以下代码:
* J$ }5 W; k1 ]& s1 h4 s# D, I( X- \4 M' v% z3 D6 g5 f& j
7 e7 ]) x' d5 o8 z! Y
. v- q) }, }3 k& ]
程序代码: / \# p. `& }8 d5 p

+ @2 w8 a2 t2 G% c& i. t- G6 f. p#include<strstream>
" |7 k. ^2 i4 k2 z" [5 s#include<iostream>. K6 G; a( U- ^& L% |  p& G% Z
#include<string>
4 S6 h- ~" Z/ y- {: Z4 M8 K0 \9 uusing namespace std;, {' n$ N( l3 h* Y; K
int main(void)
& p5 Y0 s8 l3 N& G) c3 ~{
! u! Q/ d1 u! e- s1 J4 W    string s1;7 ]. s0 C1 U0 W
    while(cin>>s1)
2 J& S3 ^/ f  M# N' p3 C    {& J. u6 }. D! ^3 C. z  T+ G8 F( Z
        istrstream isin(s1.data());
$ L: ^8 ~. `/ c# }; g4 E" B        double d;
  b* M$ S' X: F2 m5 a; ^9 i        if(fy_Exp::GetExpValue(isin, d))
6 w" E% O; d8 f8 y& y        {
# S) h1 w5 b0 D, I0 K8 z( M            cout<<d<<endl;
- C6 j3 n7 I+ k7 s9 f$ P0 G  B        }1 J/ d! ?% l5 G! |
        else6 y" r+ F! x5 w
        {9 l2 q& H' J5 N2 f0 b) {2 r, J
            cout<<"ERROR"<<endl;
7 ?7 r# x) T8 A9 U5 W4 p6 @$ L* L        }% Q" O/ U3 N- R
    }. p% D& g4 I& K5 T  Z: n
    return 0;
( M; X' I' [. t# O7 b' {0 d% W' d3 l}
0 T1 y1 Z( y7 i% x: J
: k3 C) M: `. R6 M- I% F& Z5 B' _6 t* O- e/ [- p
然后编译执行就可以了(*^_^*)
, W) e. B3 R$ Y7 p& _其它:TC++上一定编译错误,不保证在VC6上也能通过编译
6 H7 n1 f; `( P0 M      建议使用VC7或VC更高版本,或者使用GNU C++编译

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