返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的," C' t2 h1 i5 V, [
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
; n4 g3 A5 L, l只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
+ \( e4 u& |1 E参数解释:9 o3 `; a2 H: G: I+ w
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
5 h3 y/ [" y( Q& H, UnReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定5 A0 a* \/ ~. p3 d  j5 B
返回值:
& x+ L$ i$ E8 j2 _7 a( M返回非0表示计算成功,0表示计算失败有错误
. N. z+ P/ Z9 f4 F) v9 _& k9 U- b: B

; ?' o) F6 g* x
4 F% x. ^  Z  [7 z/ R程序代码: ; I" P1 C% P! b, ?8 X
9 G' M/ @( B# G! M3 c
namespace fy_Exp{8 |  E8 P2 f6 S5 a0 [  \0 r# j
namespace {template <class _T>7 g9 y- T) p& I( u9 y: \' n7 q
inline _T GetExpValue(_T t[], char& csym){
& q( ?( W+ g) W9 p2 e    char c=csym; csym=0;
6 L6 N' ]% L2 ^! V6 ~9 P3 u" p    switch(c){
( I6 u& U+ o! ^' R$ T* I    case '+':return t[0] += t[1];) G, B& b. f, t; }! ~0 u$ x& z/ O
    case '-':return t[0] -= t[1];
/ t2 Y7 @6 I3 d; [    case '*':return t[0] *= t[1];
" A- |. U8 Q! ^/ ?3 E+ W- q    default: return t[0] /= t[1];//case '/':! @2 R' _7 @9 z5 ^) g- w. B+ o
    }7 A/ j/ }+ `9 P5 ]% a! _. |; L
}}3 p+ u& ~5 q4 V4 s
template <class _T, class _Tstream>
" A1 [5 Y" a8 x% _0 E3 P8 @8 s/* _Tstream: inputstream, _T: get return value
$ n7 Y" [7 g0 h* Return nonzero if get value successfully */: @  y/ L+ Z( k5 f
int GetExpValue(_Tstream& istrin, _T& nReturn){3 G2 t; z' c4 ^9 g# l! L
    _T t[3] = {0}; //雨中飞燕之作
' B) E1 \5 y+ P3 T    char csym[3] = "++";
8 B0 |4 [  G5 r1 Y$ ]$ J& K    int nLevel = 1, nERR = 0;" T0 M7 a- D- U3 H6 [+ I5 _
    if(!(istrin>>t[1]))istrin.clear();$ [: x$ B# [- Z( {
    for(;;){
* j9 S5 ^/ p) Z: k' f7 |* l9 q        if(istrin>>csym[2]){5 X. w# L1 q8 w% x- y
            switch(csym[2]){$ j/ S; a( U$ n2 [7 _/ J
            case '(':
: X$ T: C; g, X/ G) u. ^                if(!csym[1]){nLevel=0x100; nERR=1;}else
3 b8 x# Q' g: r9 U                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;' [+ c( Z+ @+ f/ }4 A% ?8 i
                else{nLevel=0x100; nERR=1;}
% i3 L! Q* I* [                break;
" a, }. s: c( I5 {. |1 [: ~2 ^, X            case ')':* p) _6 j% K4 i. R
                {nLevel = 0x100;}break;
7 C* V0 F( g9 W2 G+ y4 R" J% a$ C            case '+':case '-':case '*':case '/':5 [2 m0 j* C+ e# y( o9 C) k6 V
                {csym[nLevel++] = csym[2];}break;
4 T$ H; `8 x7 z* P  s            case ' ':case '\r':case '\n':case '\t':continue;0 d0 K& T  V9 j* k
            default:* I  ~6 |! b. m( M
                {nLevel=0x100; nERR=1;}
. Z  W9 [2 ^: ^8 S& }( D# z/ b; M            }% U) u4 ]4 k. i  {
            if(nLevel==0x100)break;
+ u6 k8 r2 D  _, t            if(nLevel&0x10 || istrin>>t[2]){, S1 G* i1 z% f  l( s4 U
                nLevel &= 0xF;
* ?- z  y/ ~, x" A- K                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}) H9 A. e6 e: j& y# G6 L1 F
                if(csym[1]=='*'||csym[1]=='/'){' L9 `1 Z9 g  P$ d; q1 U
                    GetExpValue(t+1, csym[1]);$ x% A& o/ Q. @& t. i; s7 F$ ~
                }
+ P, @# ^3 `$ W$ c0 E* E( ^                else{
0 N7 w. P8 V/ H- l: d/ A! x                    GetExpValue(t, csym[0]);4 s( W9 ?7 \1 r6 y4 D& i
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;, F8 d0 G, c6 D" i) y6 _! T' I
                }
8 F% U* o5 x! G                nLevel = 1;- n. k- b) W, f6 @* V$ p7 }9 m
            }
( g  L' }; b6 B! j3 m7 F* z: p            else istrin.clear();
1 ~! q5 y+ W. \9 Y/ t/ r; h! G        }
$ B, x& x9 _5 G) F8 }( t        else{nERR = -1; break;}) u( V5 p" p+ c
    }
. h% k* b0 n! I) ~# a; `' N9 t  J    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
* `1 @& D9 V$ c" b% t4 p    else nReturn=GetExpValue(t, csym[0]);
, X7 ~( g! V$ F2 Z; a    return nERR==-1?1:0;7 x8 p: }/ B' H$ Y: L1 r% W
}}
, N1 g: M7 b+ s3 |7 ^7 ]4 j
) ^" j1 N3 m  P; i" y/ X$ l+ C/ ?2 `7 [+ v0 n( e! X

$ Q( h8 c+ d  P0 r- V' Q; d函数模板使用示例:1 P1 u% ^% x& T/ i2 k8 p9 ?% D
在以上那段代码的后面加上以下代码:% i$ s2 u3 G1 L. T0 O
9 G* L, h8 m) v8 a, ~3 K; h

, V; c' x* \; W' m/ L) P, p7 H4 u- F5 z3 ^8 g+ Z2 J
程序代码: 5 S" @1 q, w; T0 |
- J- |2 I( B' t& V: Z7 w) y) m5 y
#include<strstream>
. }) L8 b* k6 _#include<iostream>
5 }9 f& P$ J3 X6 U9 a8 E#include<string>8 [+ h: h) z5 ~, r8 B- O
using namespace std;
+ i& n$ x) \, c* cint main(void)* s4 D. r) m; f8 u8 f+ A% ~
{% a" m  A! |0 Y4 A" _
    string s1;
9 Q" z5 e( i: \    while(cin>>s1). _  F5 I- s: I. W6 d7 q
    {( ]2 a( {; z  ]! r1 J3 a
        istrstream isin(s1.data());
; j, `, x4 Y% Y, G9 Y5 [        double d;" n4 ?; q  Q! G
        if(fy_Exp::GetExpValue(isin, d))
& m( i: t+ H' f& h0 N) I5 W        {
$ l: M; e' z& A( M9 F            cout<<d<<endl;
' F+ g4 G7 n) n1 e* z- V7 c( ?        }1 [6 P) c3 w1 k0 Q/ O! L$ R" F4 q
        else" V7 t! l) M% A' N+ A. T. R
        {# Y# k3 y1 a3 i1 F: f& e& p/ a! O) Y
            cout<<"ERROR"<<endl;
" Q7 \( F+ o# N1 V; m* P2 a7 g. }        }
/ d2 @1 W. O3 g7 l$ {    }3 S& G" f1 [9 V7 Z6 ]" ?/ `
    return 0;
( a% T& N; N7 g, N}% ^. g5 [* Z% y1 N: X3 q
  Z; c3 p" k+ ^0 b0 ]
- V3 k* g, y+ _5 K3 R- r+ U
然后编译执行就可以了(*^_^*); g0 m0 c9 w! L, X: }% ]
其它:TC++上一定编译错误,不保证在VC6上也能通过编译& Y- I  C/ V1 w+ F$ g+ \3 f
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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