返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,) W* y/ c6 ?  K$ p2 }' v, X* `
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
: l7 G3 F0 K) Y$ d+ B: y9 ]* P只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)6 j% R2 I9 D5 }  v4 x: _/ G
参数解释:( b8 D7 R3 W0 I" m- t& H* g, b
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
1 F( ]( z' J: X! P! ~) h* p- qnReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
( |( \4 M$ r  \. ~/ T/ z返回值:. x, t1 W& m& Z9 }& x. a
返回非0表示计算成功,0表示计算失败有错误
& s9 @- {3 ^- w+ }( p. V
' W" h. ^6 W9 S: H, p5 H
$ m& t6 B/ V$ h4 T' w* J& G) S( ]- D3 t
程序代码: + V- D- n2 Z+ f1 |" B* ]/ c0 y9 Q8 `! u/ k

* m: h* h# ^3 W2 g" O; I0 a/ ], Nnamespace fy_Exp{
1 B3 E9 |' d% P, i8 y. unamespace {template <class _T>; L/ U( X# X' R+ p8 J9 k3 O( r
inline _T GetExpValue(_T t[], char& csym){# \! Q5 u- M  G* D4 I0 |0 Q
    char c=csym; csym=0;: n7 ?! B0 Q' @4 J6 ^# S
    switch(c){
3 a+ o6 S  R' R    case '+':return t[0] += t[1];
' U+ l5 l6 i" Z: I" g- p, L1 X    case '-':return t[0] -= t[1];
5 w6 Z7 k0 d) A' }) D    case '*':return t[0] *= t[1];
  J. B3 c( y: O2 w5 m" L    default: return t[0] /= t[1];//case '/':
* h3 Y+ g. ?5 [$ [9 `8 U8 O$ \$ I% c5 s    }4 Y. A- A( x4 s  _4 _
}}
9 @; I' h& f. ~' }template <class _T, class _Tstream>
6 h: b! S9 j" `/ O# c$ P) D$ h/* _Tstream: inputstream, _T: get return value
/ j' z' Z8 L8 D/ a1 T' g: E3 f* Return nonzero if get value successfully */
( C; Y. b5 D. ?( X. g* e- Yint GetExpValue(_Tstream& istrin, _T& nReturn){
/ A/ L. x; y5 ]4 F: l7 c, l; Y    _T t[3] = {0}; //雨中飞燕之作: F% V" b& P$ y
    char csym[3] = "++";
' L" \, u7 q1 z8 Z* K    int nLevel = 1, nERR = 0;2 B7 S) z; h  a# {4 d
    if(!(istrin>>t[1]))istrin.clear();+ X+ d2 e4 N5 k& Q. y
    for(;;){6 o( K% r+ t; S5 h# {
        if(istrin>>csym[2]){
. _) ?# M+ l" c( e3 F& l& l6 I            switch(csym[2]){
7 S) L& a7 |* M7 C* s! n2 T; _4 h            case '(':
% T8 r- C$ H8 R- E; n                if(!csym[1]){nLevel=0x100; nERR=1;}else& ], R0 A0 F4 o/ ]* O4 B
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;' B1 V# Y6 I+ s1 U" `
                else{nLevel=0x100; nERR=1;}
' V; c: N- K) P! s# E! @                break;; X( p$ O( @$ n3 i$ p5 D4 G% v; k
            case ')':
1 {# L) t. Y: l' w! g6 k* \                {nLevel = 0x100;}break;. `/ R4 V3 e5 K1 q: T/ K5 L! w
            case '+':case '-':case '*':case '/':/ e4 `  D7 Z( c6 K
                {csym[nLevel++] = csym[2];}break;5 i" N6 X: {1 v
            case ' ':case '\r':case '\n':case '\t':continue;7 u2 l5 {" Q5 E! I; W2 h. n9 n
            default:2 Q) C! e3 f+ D! J. g' e0 _7 K( ~
                {nLevel=0x100; nERR=1;}
* M. h7 m3 R- X. k: g& p) w, z            }% s& v& {5 i9 K  ^, A
            if(nLevel==0x100)break;9 V( B! \" a- H3 N4 @( l5 }2 ?
            if(nLevel&0x10 || istrin>>t[2]){3 i, Q8 _/ g4 b* U6 l! L
                nLevel &= 0xF;3 s! c, ~$ N+ N( D" _$ u
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}8 n5 i! y+ a9 x: d
                if(csym[1]=='*'||csym[1]=='/'){7 ~8 x. F$ V9 h; {: H
                    GetExpValue(t+1, csym[1]);' |( g8 L, Q6 e- G2 o( C' L3 u5 V
                }
, h" K: c& G7 M- _) e! o                else{/ ~( Q. ], n  @3 g0 e
                    GetExpValue(t, csym[0]);" _& a# b) l( c
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
& S& R1 [0 N3 o: @                }3 S# R4 t# `+ {# `$ J! Z
                nLevel = 1;* E6 J/ d' k" Q8 d8 x2 y/ ~3 h
            }
# h3 E& s$ s5 E$ L            else istrin.clear();- ?. h* ]  ]2 e: u7 b8 {+ S5 z# B
        }# v& f; ~5 O% t/ y2 d3 n; \
        else{nERR = -1; break;}( r1 j% i) Q: e% H3 f! N% N- ^
    }
1 `  E( t1 M7 w/ ]9 Z5 \    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);. K8 o) Z6 t( ?% q
    else nReturn=GetExpValue(t, csym[0]);
+ @" n) w2 B+ o7 P. V    return nERR==-1?1:0;7 O, B6 f3 D# A
}}% Z- q1 A, F' r0 U6 ]: X
7 y& \+ |1 l8 m1 Y7 r6 ^

0 Y5 j$ ~8 u/ w0 U' q2 U) j$ Q0 Z' b
. W0 c. ^0 u1 G函数模板使用示例:
  Z- g. O" J8 @6 L) P7 a# ]在以上那段代码的后面加上以下代码:
3 \' Q* e5 O. C8 r+ F$ m/ J6 P$ Z
) h. R1 O8 x* e0 ~
6 C0 \, d6 w: Y2 O
6 {3 U' n% P# N$ S) n9 u% x程序代码:
: u' \/ Y  O9 O3 {
3 e2 L) ^, W! X9 o5 b#include<strstream>, Z8 Y/ a4 @) F7 f
#include<iostream>
" A1 t( X: m" l6 d( w#include<string>
: B& v. @& b* e- J7 @0 W, [5 eusing namespace std;
  B1 a; y! l$ o5 wint main(void)
& U: m1 j$ M2 X. ^+ g% B4 _{
& ]" }2 @2 a, Z* }/ b2 M    string s1;4 h5 X/ E$ }) M/ }2 w  ?! S
    while(cin>>s1)+ n: O; `, m, L. ]4 J) [) b
    {# v0 P  F$ ]. C( w
        istrstream isin(s1.data());
+ A6 _3 m5 E5 G        double d;9 z7 ]8 ]2 Y6 e1 j+ d& d
        if(fy_Exp::GetExpValue(isin, d))
( o$ Z! X2 l1 g5 v4 Q) m        {
) y# d+ ~' n( w/ J8 I3 z3 y) b1 M            cout<<d<<endl;
( e: N- D1 |0 ]        }& n- B) X) B9 W4 h
        else/ S) Y7 R! l( N9 a; A# N7 q
        {4 K$ g# P/ a- `1 ^& P. C- [
            cout<<"ERROR"<<endl;4 n  E7 j/ }( O) N
        }- u! Z, p; M  B
    }7 O* v% U/ a: @: H9 D
    return 0;
2 F" D! {' ?  A2 _}& b  f9 a) p. K  v8 n( j
4 K* l7 D  Y& n+ y' G. n2 O

4 j7 {8 Q4 j' q1 g, G然后编译执行就可以了(*^_^*)& @# o  {- t$ K5 ]
其它:TC++上一定编译错误,不保证在VC6上也能通过编译: v0 g0 S" u/ l0 @
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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