返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,2 o  l( J" @; Y+ k' J
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
, z. Z  h3 U* Y" \" D$ [只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
+ J  H' ~  K( j$ o# S7 }3 ]- W参数解释:
0 Z, d% T! a+ n, X8 c$ Cistrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流, t- O- \8 W# \1 d1 x. h% j9 p/ r
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
& w. L# @# R( p* E返回值:5 t6 `$ T! c! w! q& J0 i
返回非0表示计算成功,0表示计算失败有错误
( |7 Z* R5 U  r$ C: p# k' M2 B3 k$ L4 C% l% s

! J( E# X% N3 [: v0 k) k" n7 s  u' M/ l( O( B
程序代码: 0 J# t, ~# U# E6 v& d

7 {: N% b% s! C0 [# J4 gnamespace fy_Exp{
# B: n) w1 T$ o' U8 B1 F# Nnamespace {template <class _T>
# F. _  w" \& m; e& }inline _T GetExpValue(_T t[], char& csym){7 K& ]8 ~% u# M! r  r  u0 t: T
    char c=csym; csym=0;
0 [: b: T. a3 |# x& L2 d    switch(c){
, F- [. Q9 v  u# S3 N    case '+':return t[0] += t[1];
3 e% X- r- g9 a3 h( X$ Q9 V  }    case '-':return t[0] -= t[1];
2 ~2 V# p! Z% \* f    case '*':return t[0] *= t[1];- o, Z9 O' o3 f" ~) `
    default: return t[0] /= t[1];//case '/':
! }* G6 ]- l- f0 s6 A7 D    }
6 \' K4 _7 H4 C3 v  b}}/ R' B+ Y2 V- S' d; [7 b
template <class _T, class _Tstream>5 C7 U6 y) B% c* @2 Y( R
/* _Tstream: inputstream, _T: get return value
# a5 P# s& n$ u2 m' ]* Return nonzero if get value successfully */
9 P' e7 Z; R" m0 J. s7 iint GetExpValue(_Tstream& istrin, _T& nReturn){
0 ]+ Y0 p  B7 W) {  ^/ W    _T t[3] = {0}; //雨中飞燕之作
' C2 p5 d/ l' j8 w3 |# f) E    char csym[3] = "++";
9 @( H5 J% m# ?    int nLevel = 1, nERR = 0;( E& j: o$ `2 D) a% }' I# x- Y
    if(!(istrin>>t[1]))istrin.clear();
( h5 m9 j* ^8 N/ `. i' S, e& c    for(;;){+ ~, Z1 {& Z1 ~% m$ D, I
        if(istrin>>csym[2]){
* v  k* T0 u  H! [1 B! T9 N            switch(csym[2]){
/ h5 |, C4 c4 z6 U* ]            case '(':8 ~! {' o6 L% [2 \. E
                if(!csym[1]){nLevel=0x100; nERR=1;}else0 l# S  i8 S! d# z1 T
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
: t# {2 i9 c" J( ^. c9 b                else{nLevel=0x100; nERR=1;}
# b% D" z/ a; v, L- n/ j                break;
* Z4 }( ?0 H5 S8 v7 U8 n. S) F            case ')':
# L$ c( X9 u$ b7 M9 M2 F                {nLevel = 0x100;}break;' |- R/ x  S2 [' {0 o3 Y
            case '+':case '-':case '*':case '/':
, ?. c( |& s  d. h; {                {csym[nLevel++] = csym[2];}break;# M" h7 e+ ~, L; |; B! G8 f
            case ' ':case '\r':case '\n':case '\t':continue;( M# |+ T8 h  F/ r; a
            default:5 A* I, V9 U& E8 ~
                {nLevel=0x100; nERR=1;}
+ _! P+ K, \% w5 J1 n4 [6 }            }. D7 H2 @3 u, o$ v5 k4 @
            if(nLevel==0x100)break;/ Q7 Z; Q) M& X& q3 [/ O
            if(nLevel&0x10 || istrin>>t[2]){5 n& U* C8 j# S' M* U+ K
                nLevel &= 0xF;2 N+ V* M, \) i5 F  s) O! w
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}) B4 d) w. R  F" [
                if(csym[1]=='*'||csym[1]=='/'){* W% P9 W- k: g( s4 M1 B2 i' Y
                    GetExpValue(t+1, csym[1]);
) t/ ]1 Y' |- Q9 e( O  k                }
5 {5 Y+ T- Q6 x3 l$ S6 _                else{# e" O- x: |: [1 a1 d2 W8 }
                    GetExpValue(t, csym[0]);
: f3 w9 t+ V* h                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
+ l# B& V* Q8 y; D! D' d2 L/ S& t                }
4 \" ?) g/ T% Q4 ?: L                nLevel = 1;
  x; [/ u9 c! |/ |2 B* w- g            }
! }# |* K* G) b            else istrin.clear();
1 m9 t8 {  K: J' q7 i2 s        }! |- }$ c: k7 M& f
        else{nERR = -1; break;}
( X% ~$ T2 a9 B; l, W' J    }4 [# t+ P0 B& S4 y
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
$ e) S" O" |& R* h9 R5 N& o2 C    else nReturn=GetExpValue(t, csym[0]);
# k1 T0 u% n& |4 c# E5 D    return nERR==-1?1:0;
! V, z8 p5 ], t}}
: G) L2 I3 @/ _- I0 X# S3 v8 s: w$ x* y9 A

/ M& n6 M' z' p7 I$ J/ w
1 j/ {! L1 I) F0 R! [函数模板使用示例:
0 o& i1 n  Q' }! [5 g! O在以上那段代码的后面加上以下代码:9 _% z1 m) P1 V2 @& m0 q

; A' \! ?9 K" `7 r6 R2 f / l. T( H7 X' ^# f, H
3 ]9 ]# f" {" @; `  ~. n
程序代码:
5 {/ G' D" Q0 L- W# Z' g" {
3 h$ w3 C+ w$ k$ Y8 p9 N#include<strstream>* ^* j% L* C4 @8 P8 [
#include<iostream>/ ^% Q0 Y& q& d: ^
#include<string>
: M" c3 \6 }8 z& D; H9 Z9 ?using namespace std;
# C3 s" V( Y% ]2 P# q) X- y1 |- Vint main(void)$ R: S' Z* [0 p8 T2 o
{$ c8 c0 T: t' I( l: W8 [8 w
    string s1;& i6 @6 f4 c( _; B0 [- h
    while(cin>>s1)
& O" x. {# ]8 M8 H& f    {
+ a: |1 R/ I% M% O6 a( ]2 d5 h        istrstream isin(s1.data());5 R) @2 M( Y* \  d# Y! t' o
        double d;
( k4 M9 K; w" {& _) }0 [        if(fy_Exp::GetExpValue(isin, d))
4 i) p& O7 F3 r0 G! t        {
9 L3 ]& V$ K0 p! T' n1 R+ R5 G) Z            cout<<d<<endl;
1 I+ M+ y9 b  N- @' H' G        }
4 v! D  M8 Y& p: ?) V5 J7 H: C. t        else4 l, g% N- `) z; Q4 K- f- D
        {
0 g! B! y- Q! F; w; d- {/ ]            cout<<"ERROR"<<endl;, K( U2 p7 m- G# _8 f* y4 Z9 E: B; b
        }. L9 {) x3 s8 j7 P& E- ]
    }5 v) t# d9 F- h" E3 d
    return 0;5 x4 z- y; Z( q/ X# E2 s% b
}4 W1 E) ~/ r0 y  u% A
- _% G3 P: k3 P, m: S/ m

# ~0 A8 h8 ~" A0 ^. ]- h5 E然后编译执行就可以了(*^_^*)
% G5 Z* M. o3 i; Z3 K9 L9 I其它:TC++上一定编译错误,不保证在VC6上也能通过编译! y; t) i; r# d, ~, w/ w2 l
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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