返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
5 c8 S' z  d( C1 `/ v4 \一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
0 g' z; x9 U; s9 o只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
+ Q* g/ Q0 p5 X; h9 O0 @- [参数解释:- T) ^/ a8 P# h* O- Q
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
; A1 U$ d3 J. A* i. enReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
+ j9 C; B; x* b8 E' c2 f& s/ ?返回值:
  A$ B1 s' g& e0 V) C6 }! `返回非0表示计算成功,0表示计算失败有错误  |! @% V( U$ r5 L9 o  L1 e8 Y, N

9 V. d1 A0 v' m7 H) y8 ?" W4 h 4 m4 y3 d  N% q: T; L( q
" f- T- T1 t( d+ L$ K7 B
程序代码:
$ L- A9 Z3 Z+ ~
0 n. D1 D8 Q  {namespace fy_Exp{  O4 c' I! k# A4 w. f! \
namespace {template <class _T>
- w2 e8 M. n% k3 sinline _T GetExpValue(_T t[], char& csym){! q& _. d) W; O$ C9 G
    char c=csym; csym=0;& r4 ^, x0 C, v
    switch(c){
; ~6 T, D. `, v    case '+':return t[0] += t[1];, [* m5 }1 q  {4 U1 D9 D8 z/ J
    case '-':return t[0] -= t[1];
7 @4 v/ S* g$ U; \4 j3 T  S. E5 E    case '*':return t[0] *= t[1];
9 |$ Q# |: z& r+ n8 [! M: z  r' T    default: return t[0] /= t[1];//case '/':" B9 F6 T4 |6 h9 T  p& F" g8 H
    }
: p" X' c9 u5 `$ j6 F}}
3 U! E* `  ~0 `, etemplate <class _T, class _Tstream>9 d$ c$ o5 y6 H' {! x- i
/* _Tstream: inputstream, _T: get return value
! m9 `$ G4 G0 e* Return nonzero if get value successfully */- G& \4 r1 W+ p* q
int GetExpValue(_Tstream& istrin, _T& nReturn){
/ _6 U' n9 W; \7 V" ?    _T t[3] = {0}; //雨中飞燕之作
# o7 Y1 j- [3 z/ C# k" ]3 n    char csym[3] = "++";# y% f. i6 u4 L0 j/ x
    int nLevel = 1, nERR = 0;
1 ?, J% |3 u: m0 {, H& V    if(!(istrin>>t[1]))istrin.clear();
, N' H8 C) K: z5 c, U    for(;;){
0 o! X, y& {) f- ]2 F' w        if(istrin>>csym[2]){
$ r3 h3 @% b8 H& K            switch(csym[2]){% A/ ?9 r  ]" X
            case '(':
+ z/ i# q/ r4 G$ C                if(!csym[1]){nLevel=0x100; nERR=1;}else% ], v* N& m, o/ M
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;/ Y* Z% l2 Y# h8 n! E, @- j
                else{nLevel=0x100; nERR=1;}
& P  C& ^8 z" ]/ v* p0 J/ A/ Y, n5 O                break;. V" F6 o8 b# [4 b# o. w
            case ')':* w% ^1 N1 _! P" w
                {nLevel = 0x100;}break;. a3 z5 M% l) a' Z" @) X1 S9 P
            case '+':case '-':case '*':case '/':
! f) d8 w% {* r8 Q  o) E9 w* o% t                {csym[nLevel++] = csym[2];}break;+ N0 m9 @# F  t
            case ' ':case '\r':case '\n':case '\t':continue;
" J! y7 c3 ^- R, V/ D& b# M            default:
- m4 _) T" q- S, M8 f: O                {nLevel=0x100; nERR=1;}
3 t8 d; t5 p$ j8 `# L7 ?) K            }
9 \* _- R9 k7 s0 ]% D7 L( }3 F            if(nLevel==0x100)break;
9 _( I' T. h( B5 x& m. l0 s' v% p            if(nLevel&0x10 || istrin>>t[2]){
. z7 h* p% r$ c                nLevel &= 0xF;
) C" c5 m, W5 [, _" Y2 k: `                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
& Q' y- I2 e; P                if(csym[1]=='*'||csym[1]=='/'){2 K* A* f0 t  T0 `7 N1 y
                    GetExpValue(t+1, csym[1]);
* N8 A9 m2 r8 ]0 b( o                }
( m. E$ G( h1 u2 q* `                else{* T$ @6 X- M- d/ A# i9 `  ?9 U7 q
                    GetExpValue(t, csym[0]);
; g- b* U2 E5 p1 l7 M/ S) Q                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
- D5 E6 \8 u" I                }
( B+ I' a$ i: w. s' [& h$ v                nLevel = 1;
2 p" |, Y6 W! D* S' {: L            }% F3 y) c4 b) _  m
            else istrin.clear();
, |: H% h$ m; ~: m: d$ _        }
( @! M: A# T# x( C- k        else{nERR = -1; break;}0 `. f6 G4 J. o2 [
    }1 o. X0 O1 Q$ C; c! g% `. H, H
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);# Q9 m1 ]& U  N8 w, N1 I: ?
    else nReturn=GetExpValue(t, csym[0]);
$ |/ a! c- R. s    return nERR==-1?1:0;3 m2 M$ ^' d% u) o# L# y# K7 @+ }
}}
1 z7 b; q4 p" @5 Q' t$ q4 U, K' G6 d9 [; z! e! `7 ~8 y
9 R& h1 O9 {3 ^9 Q; Y

! b" u- _8 X- l* ], Q6 X$ b函数模板使用示例:
$ z5 k' n, c% N: _1 E) K" F在以上那段代码的后面加上以下代码:
4 f9 w, A; V0 ~7 R" A3 ?& b9 D5 O2 f( d2 j: J7 K4 a, }+ O: W
, a& }, _+ [' i# ?" {9 ^

. \* j3 O) t4 i程序代码: 2 I( x! j2 _; y9 P8 V$ n
) M# Q+ R% i$ K& ^
#include<strstream>; Z7 A/ Z6 Q7 O
#include<iostream>: K' y. N3 k7 O, t0 ]' y0 }
#include<string>
& q9 V7 j% [0 r8 Q. O& V+ Dusing namespace std;
: k6 G- u/ v  M& K2 Jint main(void)
, A) ?) O; I9 N6 S4 ]{
2 T, z1 U0 Q4 a& ]& {) D    string s1;
/ u. D* p6 i/ m, ^6 {    while(cin>>s1)& \. N$ z, Y5 e/ K7 a
    {! T" b0 \" ~  t. Y' g
        istrstream isin(s1.data());3 T9 ~( W' h8 K$ o# N
        double d;" b% I4 N: }! {( Y1 o$ s/ S5 E0 F
        if(fy_Exp::GetExpValue(isin, d))
2 s; g/ @: G0 m        {/ O$ J  O; _3 n* N6 @+ ~
            cout<<d<<endl;( Z  a4 a7 D, z) |' _. @
        }* d; m  I% I. M" f/ T6 [
        else6 @4 p% g8 G& G) N
        {
! E8 E) r; X6 {            cout<<"ERROR"<<endl;4 Q1 I4 j3 v( ~- ~# |
        }
0 E0 r0 ]7 z, T- R4 e- K8 }    }3 W& @1 ~- Y' e+ I& U) D: s- T4 F
    return 0;
& m7 q1 `! ^, u) C+ Y$ T! I+ |}
2 H: p; Y( v6 U. R
% E% t: \2 Q  h  U
9 E/ K4 k! L3 g然后编译执行就可以了(*^_^*)
, W) @0 N$ W. u- @其它:TC++上一定编译错误,不保证在VC6上也能通过编译
4 s+ D: E8 V6 m% O5 C4 ]% S      建议使用VC7或VC更高版本,或者使用GNU C++编译

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