返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
. b$ ?" B6 |% e3 c6 y4 V' m一个很方便的函数模板,可以并且只可以计算含括号的四则表达式" @6 ?! o; K8 {  R( ?" A" g
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
; t* v7 V. o& T. P6 B& A% ?参数解释:
( R& x. a- B6 E0 e9 |" S& Tistrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
* \2 Y; g% T& ^: @  L; K6 U8 N3 A! AnReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
. j) j( a7 P: a* j返回值:, w/ w: {: Q* Y2 C  R
返回非0表示计算成功,0表示计算失败有错误. \9 y! j  ]3 @$ w6 p- m

. }1 G  A) ~1 C1 D0 X* x2 \: K
9 [3 W! A, k+ ?  b5 P  j+ w- `; i- w5 \8 @: }! a1 R, G
程序代码:
0 J8 f- J7 p* G% i8 C5 I% ]3 t, p- v, x$ f
namespace fy_Exp{- \' ], `, R& u
namespace {template <class _T>
% e% M+ ~& C4 d% d) q& r8 t0 {inline _T GetExpValue(_T t[], char& csym){
/ O9 l# L1 E1 E1 `. O    char c=csym; csym=0;; s# `# f* S- [2 @9 n! H
    switch(c){
- M- i9 ?( @' Z* b6 \6 b3 c    case '+':return t[0] += t[1];
/ n9 D5 U: }) H; ?# F    case '-':return t[0] -= t[1];
! U' ^2 n. v4 n/ P, ^    case '*':return t[0] *= t[1];, M7 m8 {5 [9 y0 L0 n: T
    default: return t[0] /= t[1];//case '/':. S" n3 _- ?" p! M
    }
/ k- c( Z- F( _) d9 k: ~}}) I( I4 l. Z) I0 }$ t
template <class _T, class _Tstream>2 f4 |8 ]1 A7 w! k
/* _Tstream: inputstream, _T: get return value# l% _- g& F) u3 z* a& V) f/ \
* Return nonzero if get value successfully */
& J9 V7 _- I. r* N" h6 Nint GetExpValue(_Tstream& istrin, _T& nReturn){5 g3 u1 I6 A( [  w
    _T t[3] = {0}; //雨中飞燕之作
3 t' |$ Q0 ?1 o    char csym[3] = "++";
' z# A2 E8 d' t' k- R6 f    int nLevel = 1, nERR = 0;; j7 E( g5 _3 b: G5 f9 n
    if(!(istrin>>t[1]))istrin.clear();5 m, F* j. O" [; I3 c6 W; L! X- h6 g
    for(;;){
* u$ F: U9 r! l9 _" g% ]1 |' g        if(istrin>>csym[2]){$ {1 @. n6 k% x0 c' |
            switch(csym[2]){& ?6 t) @& E1 _/ S! i
            case '(':
7 Z& U/ @- a' v                if(!csym[1]){nLevel=0x100; nERR=1;}else
+ |1 m+ {& W/ T9 i* \                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
  t; F& L7 j2 Q# I! {0 m                else{nLevel=0x100; nERR=1;}. {; }1 B* [( E( D4 Q! @; s
                break;
* {  M  Y& h" {# J4 Z/ d' A. [$ V            case ')':
1 m6 Q3 I7 U# w) i. s/ c5 A" A                {nLevel = 0x100;}break;
6 i. Q; z2 W1 g4 }            case '+':case '-':case '*':case '/':
  I7 B& }6 A% R                {csym[nLevel++] = csym[2];}break;9 n/ D* ]+ ?% Q5 w
            case ' ':case '\r':case '\n':case '\t':continue;7 ?: _' V* k6 s# }7 q
            default:4 [/ X' u' [" C5 |8 R2 e
                {nLevel=0x100; nERR=1;}. C5 i) n. D5 F3 {2 O
            }
8 J5 }, D$ r6 Y3 G4 n) ?1 @            if(nLevel==0x100)break;
% t+ E) I% X& D+ D4 m1 A* G            if(nLevel&0x10 || istrin>>t[2]){
; [' t" _8 E$ [9 D4 V" {& {                nLevel &= 0xF;
& ^, c# K( y0 x                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}$ A& w! \5 e1 D/ H( _
                if(csym[1]=='*'||csym[1]=='/'){
7 W+ A/ Q8 \6 f2 k9 W0 N                    GetExpValue(t+1, csym[1]);
% R' `  `% z4 t3 v' K- B                }' ~1 p- b. b4 o8 @& i- K& Q
                else{
; O: G5 |6 e+ X                    GetExpValue(t, csym[0]);
3 Y! e+ h4 ^/ C* b1 k                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;6 R6 C( X3 j* D7 q$ j. t
                }6 {0 k' B1 e2 W, k2 Y$ B1 N
                nLevel = 1;. O# r4 W6 H" g, Y6 W) s: D
            }
/ S. l$ R; _0 B            else istrin.clear();0 V( Y3 S7 C5 Z4 c7 {4 v. _
        }" u5 v, c5 h3 i. B- _) Y: ?
        else{nERR = -1; break;}
1 D8 S: p6 A" P. a/ t9 {    }' a5 t  O1 ^% |+ W+ H2 ?0 \
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);! e1 B: V; I5 U4 h% c
    else nReturn=GetExpValue(t, csym[0]);
$ T" G" K$ @0 c7 i    return nERR==-1?1:0;
2 U6 R3 O& ?8 P7 U9 H# s/ m}}
' r$ o0 s2 z' a1 V2 f
  i  Z* z( k; L& C
: M/ d/ A6 x* p' v" w2 C0 `9 _8 I2 F
函数模板使用示例:
( q4 e+ z/ f* Z# [6 a: s# j在以上那段代码的后面加上以下代码:
' W( z( f* u7 ]# Q! v8 R5 Z1 Z( p0 f8 h. B4 ^6 E3 @: L+ e

  q5 ?4 b/ ]: y
2 j0 i- p$ J6 p% F* @& k程序代码:
. \( X0 l3 p  U+ ~
3 p+ E$ f$ G# e- J6 Y#include<strstream>5 E' F7 V6 \3 `1 ?+ g4 o* ]
#include<iostream>$ E( B  @& Q* L4 {- B9 J- N
#include<string>
0 ~+ _4 i5 b! F- _* A' b$ B% Pusing namespace std;
. N0 T" c3 F2 T  D7 S% R$ Zint main(void)
0 |* P9 G: a6 `1 T3 g. j- B{" ]5 L  s! \1 b2 k" l, E
    string s1;
, I1 R; I" U: q% x5 N+ `. V, q    while(cin>>s1)3 D# [2 a9 N; w& ]( n$ V2 u
    {
/ A5 ^& c# G: n5 _! R& Z" L        istrstream isin(s1.data());+ S. D6 j1 [2 E$ j; n3 ?$ \
        double d;
* x6 M: f  i3 A  q9 d        if(fy_Exp::GetExpValue(isin, d))
- W& S! d0 Y0 C* v- d/ D$ B9 B        {
& q% j' d" z* Y3 L, O3 y            cout<<d<<endl;7 h- w: P0 ?  D7 B* z- E
        }
  n; i7 x" u& ^  S4 B2 d( O% W        else9 R- k+ @5 T4 ~
        {
4 R4 l* Z" P6 @( N            cout<<"ERROR"<<endl;/ E9 R; U: z. U0 r+ M
        }- J+ N' I/ e1 ?9 Y) A
    }
/ D  d* k9 G- s0 u2 N* ]! m    return 0;0 h! o& r! d9 ~" T
}
/ m$ @7 i! L" ^/ M( p
; Z  G+ X6 k( g- U5 \2 O; B1 [! T( X% V+ j4 {# r! |
然后编译执行就可以了(*^_^*)+ t% t0 U9 E' y# i) e6 p
其它:TC++上一定编译错误,不保证在VC6上也能通过编译
; x0 Y9 k; _9 R7 [  M0 q      建议使用VC7或VC更高版本,或者使用GNU C++编译

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