返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
) L2 t# }/ [2 ~8 ~- d一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
* }4 g' k! O3 u# g4 T+ y只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
/ _4 U# E- M& M0 Y参数解释:" l" U& ?# [# [  a
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
4 H  P2 }% U# u' |# R! _2 @nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定; M& F+ l3 y* R+ Q: E; F: l1 N
返回值:' D3 Y- K2 B& R. F5 {; \
返回非0表示计算成功,0表示计算失败有错误5 u& E9 z+ g+ S8 D; i

, q  C. M/ E* F" ^3 d) ~ . U) u& M# R3 e7 _' Q/ N

# z, s2 D% c6 K0 J+ o  A3 x) ]程序代码:
% Q8 d% Q- i5 t/ ^2 h- T5 ~% q5 B2 D- t' h
namespace fy_Exp{
: S9 i3 a7 o# a3 Inamespace {template <class _T>8 P  f3 ~6 t( R" f9 _0 O9 y
inline _T GetExpValue(_T t[], char& csym){! Z' A- W. E% I' Y
    char c=csym; csym=0;7 }& V* B2 A, t* n1 T' |
    switch(c){3 G. K% A; _9 w5 A+ e
    case '+':return t[0] += t[1];. T1 N! U' [7 ?0 m- i
    case '-':return t[0] -= t[1];
- H( ]+ K4 q) f    case '*':return t[0] *= t[1];# h( o% Y5 }- s! k1 {
    default: return t[0] /= t[1];//case '/':
* e4 n. e, c: ?5 n( z    }, [- Q# Z( _; _# Q
}}8 d7 h1 H- f2 n3 t
template <class _T, class _Tstream>
  v% m1 l! s7 v- j8 w4 O/* _Tstream: inputstream, _T: get return value
. h( K% n7 s& e( ?* T9 j  U- V* Return nonzero if get value successfully */
' N$ `+ {' ?! z# i0 p/ [; Nint GetExpValue(_Tstream& istrin, _T& nReturn){9 a6 _; u3 m7 v% ]* p. ?3 M
    _T t[3] = {0}; //雨中飞燕之作4 H! p  d; y- C# H: m
    char csym[3] = "++";
" V* g* u2 j% q% B    int nLevel = 1, nERR = 0;5 B1 K) a& c  f+ x1 L' g
    if(!(istrin>>t[1]))istrin.clear();0 i) B6 h( n2 c4 e9 R& j* b
    for(;;){, C' H2 {7 R6 ^
        if(istrin>>csym[2]){
" ?* ~4 W1 q& _# ~            switch(csym[2]){
4 H4 M7 _. w- W# s            case '(':! z: G$ [, G$ q: B& k7 H" p
                if(!csym[1]){nLevel=0x100; nERR=1;}else2 }% p/ F' _+ e1 w  p- }
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;$ q" @3 u! r2 u7 r/ Z; K; |( Y
                else{nLevel=0x100; nERR=1;}! @8 {  Y7 d# x: }: H. J: _
                break;& z9 V9 ]1 ^$ B$ n
            case ')':) l% }+ Y5 \9 I1 d# a
                {nLevel = 0x100;}break;
. m" c6 S% ~! r; O            case '+':case '-':case '*':case '/':
" a4 D! j% b7 }& \                {csym[nLevel++] = csym[2];}break;
( O1 l3 e/ T7 e" R) W. |& u            case ' ':case '\r':case '\n':case '\t':continue;
( [0 P% z% Z- U4 M) k* Z6 e            default:
" E# ]0 x1 x1 m3 z( n# y                {nLevel=0x100; nERR=1;}
6 O* l+ @0 q$ h( n" k) t  I" @            }
8 U" j0 L0 K4 J, O2 V  G# c) a            if(nLevel==0x100)break;
2 ?( [% E  P2 ~; W            if(nLevel&0x10 || istrin>>t[2]){
; ^. W/ T) a3 P2 A' W                nLevel &= 0xF;5 |% H! f7 q4 x  O6 u8 w4 t9 B. D: @
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
" R6 S* l; I, D" G  f                if(csym[1]=='*'||csym[1]=='/'){
1 T9 r- C$ M6 ~5 u                    GetExpValue(t+1, csym[1]);
4 ?7 i' f5 ~0 l; N8 ?! `# B. B& g( v                }) Q! F# T) q0 c! ]) ~& V
                else{
0 `$ m7 o) d# N" d, O5 K; l& D$ }                    GetExpValue(t, csym[0]);" {7 N; i/ l& R! ?) c% J
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;9 b5 D! P. B7 p) y4 _
                }5 {6 Z, e& P' Z# s6 V/ V  @7 d1 O
                nLevel = 1;
9 P3 a4 |. L# ~8 F1 a- I! L            }& |9 c: N* P2 d- k
            else istrin.clear();; f, D1 p' _7 x0 N5 h7 Q
        }
# N' a( k) k2 c6 i        else{nERR = -1; break;}& {8 Z3 F: @& u  ?* o4 R. S1 a
    }4 P( F0 F) T2 J0 H0 s6 Z
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);; Q7 v8 \- F& J; M" d, J' t
    else nReturn=GetExpValue(t, csym[0]);4 B% r0 p0 N$ G/ j& d* U
    return nERR==-1?1:0;3 e2 T' N! @( t
}}. S1 H1 k9 x( {+ c3 m  S# J3 S' z

2 k- [3 Y& U: y! H" b8 b/ F' H* z: ~6 m  V. [  X5 p! d

  n: R! H( U/ \. ?% M函数模板使用示例:
& X- c( h6 k2 c在以上那段代码的后面加上以下代码:* f( p4 h. ^2 ^

; w5 b. g0 y7 Z5 I) e8 w' Z; t 9 o* w5 t; U  z5 w
. N; f3 R, W7 Z2 q" S" z# |
程序代码:
' r; d% @, |. I- l0 s, _5 }
; }; d+ j# z2 _1 m#include<strstream>
, D( }1 a+ ]1 h4 {! O- f#include<iostream>
' x, _7 T! y' {: A#include<string>
3 w: k, T/ r3 }" V: n' H5 ^* E6 y& |using namespace std;( M; p9 t2 V% x8 k( a# r9 W0 v
int main(void)) Y: p7 ~' a% N7 X( @
{7 Z5 |. d, W8 [  Z
    string s1;
7 S& B7 X3 b5 @    while(cin>>s1)
; R: u; c* N; S8 z6 ]    {
8 f4 b! N8 ]' E- Y/ f1 o/ s        istrstream isin(s1.data());+ |7 {2 i% N% f9 e- t" T
        double d;' e  c' m  K: N5 m! C
        if(fy_Exp::GetExpValue(isin, d))
, h6 ~; @7 a! k$ H9 q4 n/ |        {" ^+ n# ]. C; v" U2 ~$ o$ s
            cout<<d<<endl;3 h1 p0 D4 Z: Z+ C7 @
        }
+ E% {! C5 B. N/ i; S* E/ a1 r        else. S4 _* c+ M  Z( X! O/ d
        {
, z9 J' Y$ S2 ]5 s3 y; l            cout<<"ERROR"<<endl;4 i& ?5 S9 m9 P6 n# o1 D
        }, L3 g" N3 N4 s6 S  x* H* C
    }
9 t( y' \; f% Z0 s. p9 G    return 0;
$ c% d; o" m" I1 ~1 ]7 R# f}
; j, C. M- |7 @4 @; j5 G
+ G! ]! t4 Z( j4 J/ T! q0 g
' j. U) H3 k# F3 ]然后编译执行就可以了(*^_^*)
8 W. Y& Y. H! G其它:TC++上一定编译错误,不保证在VC6上也能通过编译! @, @3 `5 p6 W) H; V7 N! A: q& O
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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