返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
$ Y: O7 {; _; C- ~. h一个很方便的函数模板,可以并且只可以计算含括号的四则表达式" @! }8 Q5 C) E6 a& _# D2 j
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
- s4 B) N7 p. X+ T参数解释:" O& L+ U3 Z& q8 G+ G+ |& Z
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流( q! ~( o% W' ]5 t' ^
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
, Y; v! ~/ `* Y- p返回值:$ g' ?& E* w  d5 @
返回非0表示计算成功,0表示计算失败有错误& U; v7 G6 E: y# [( |& w

4 f4 V' n6 _/ u2 S! G 6 e: {5 Z  u& n7 n

! S$ G9 d7 X* j  s! N程序代码: 3 }4 ]5 T) w/ n/ c# `( l

+ ^/ F) h4 Q$ Y  g  m2 X$ Pnamespace fy_Exp{, U$ u4 ~- `, a* R- b, u
namespace {template <class _T>
% t$ y- ?" }% s8 T% Zinline _T GetExpValue(_T t[], char& csym){/ z6 J6 U8 L  U0 J& s! u. u
    char c=csym; csym=0;4 c  s: U5 q" [3 {; K
    switch(c){
9 M. W! r$ @1 w+ {  {    case '+':return t[0] += t[1];- B6 v; r9 R0 h. k
    case '-':return t[0] -= t[1];
4 Q" O4 a- M/ ]% I0 f0 ^+ b4 e    case '*':return t[0] *= t[1];% _" p* [& ]3 h0 r% J* z3 Q
    default: return t[0] /= t[1];//case '/':
. r' K2 Y9 b0 o4 d$ a) q    }
7 T& }5 R& b5 ?  C2 i9 l  a}}
; Y5 d4 a1 A9 c- Jtemplate <class _T, class _Tstream>
; H' F: t9 R9 F" [1 B9 P3 C9 R/* _Tstream: inputstream, _T: get return value
, X- ]$ `; a0 c* Return nonzero if get value successfully */$ o) k7 I9 y. `
int GetExpValue(_Tstream& istrin, _T& nReturn){
, J' N' I! m( Y9 _0 s; _( x; K    _T t[3] = {0}; //雨中飞燕之作
) ^, `4 _6 p( h, m3 {; a    char csym[3] = "++";4 F2 q4 L% f  J0 z! ]
    int nLevel = 1, nERR = 0;8 c, a& O3 o; i. S1 v, [
    if(!(istrin>>t[1]))istrin.clear();) n1 H' Y; }9 M  y0 M( E
    for(;;){% Q# `, P  b1 }% G
        if(istrin>>csym[2]){
3 M: B, D2 n0 a0 h& k5 y            switch(csym[2]){& @1 a0 @/ F1 z5 v6 u
            case '(':1 x" M+ W' S* p7 x/ s' @
                if(!csym[1]){nLevel=0x100; nERR=1;}else
1 V; R' K, U" b# _; M( o1 ~                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
) G$ f' Q0 I! D4 Z                else{nLevel=0x100; nERR=1;}
- L2 w0 W# d, x, |( R( f. e                break;
, |: s3 X- f3 O3 C( p$ z            case ')':
6 y  V9 o5 @5 W+ N5 w( k; x" ?                {nLevel = 0x100;}break;* f, L' V' ?" W$ Z
            case '+':case '-':case '*':case '/':( n( Y- g" ]. i" v
                {csym[nLevel++] = csym[2];}break;0 \" ^0 x; Y. N+ p6 o
            case ' ':case '\r':case '\n':case '\t':continue;4 u& s3 m, d% d; k8 T/ l& o
            default:
6 o$ f. P4 f1 r& ?                {nLevel=0x100; nERR=1;}% K% G' k8 {. t( G* c1 l
            }( b; s! [# k  V" u# o
            if(nLevel==0x100)break;
# }8 `7 m3 F8 U' e* z; H            if(nLevel&0x10 || istrin>>t[2]){6 J7 _1 u& f" ?3 W) v' {
                nLevel &= 0xF;
( n0 T& m) G* P) v+ o- ?                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
, P% T( R/ ~" K7 Z                if(csym[1]=='*'||csym[1]=='/'){7 t" I$ M* R1 x
                    GetExpValue(t+1, csym[1]);
9 w; d" @& n) ~- d5 E                }3 n! j# {4 Y6 ]
                else{  N: }$ {/ e7 ]
                    GetExpValue(t, csym[0]);
) A6 A, q. l: O( A9 y  {0 A$ H. ?                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
6 z' U" h* F" C- c; K7 `; \' [1 |( O) n# e                }- F; J  O0 |$ I: A; O
                nLevel = 1;
2 P- X6 x4 u' J. q2 }' ~            }0 J1 ~& [  O( f; y- |, N- |
            else istrin.clear();4 `4 j# \. y3 g4 p( v4 e
        }; R9 O! K9 U7 ]! I  D
        else{nERR = -1; break;}
3 ~2 U( |3 d$ I) j    }
* N6 }& h0 Z4 i, Z    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
$ s2 D; y0 j+ r  h( X2 c    else nReturn=GetExpValue(t, csym[0]);4 O* O2 r9 R: \0 Z; \# }1 g
    return nERR==-1?1:0;# u& {" I/ a- V& w3 b& ~
}}2 d, L) }8 ?* P8 N0 U7 _

% X: L, S1 V; }- ^2 O% m" b# L# T: q7 {# H6 B5 _( z" Q" K. `
2 r3 k& v( U/ M9 e3 W' {
函数模板使用示例:
9 l1 \8 r- t* j2 Q; ^在以上那段代码的后面加上以下代码:
5 \6 _7 Y# R) d# C; [
( A1 w1 L+ X4 P& o) K ' D! }) ?' i" T1 ^6 c$ Q

2 @2 u" Q4 N' Y! p程序代码: ( k: @- k& p9 ]! K) b! F6 Y

5 N  K7 K$ V1 i3 [$ s3 w#include<strstream>
- D% t! \7 F* b- W#include<iostream>
1 J, D; v8 T. Q#include<string>1 d( N. o0 K9 A, X& O6 r0 L: M
using namespace std;
, L$ e3 h$ m) K6 _/ J1 i8 A& Oint main(void)
) K+ j  ]7 x3 K% q. d{* w; h. }) c  F& R) Z' r
    string s1;7 w8 {; d7 P( o$ F. F/ F
    while(cin>>s1)+ H$ E0 f0 |# \$ w
    {" O% Z) z$ L9 Y" K: s4 ^
        istrstream isin(s1.data());) p9 V. m8 m; {& a& F/ v$ y: F
        double d;# |0 a# B* ]1 N! p6 i# H8 t0 h' f
        if(fy_Exp::GetExpValue(isin, d))' a5 z4 n+ ?' K2 c4 M& W' {' y1 I
        {
/ x) ~; @  Z8 F0 F- G            cout<<d<<endl;
9 k9 j  |5 ^# R6 Q) D. d        }
- O% b6 D, Y9 f* _        else# V0 i+ V3 g* I2 q9 u
        {
( m( s, j, O8 k. E0 \/ U! X            cout<<"ERROR"<<endl;
5 P$ w9 i- ?5 q7 K( Q8 Y' @        }
& B, x* P" x% `. X' g6 |. c    }
# [% j9 Z5 p$ M: O  y3 g% S    return 0;
4 J  n+ T9 x* l  e}
! f. |% \  F3 l8 ?+ ?
  J: e5 }) ~, W# W) {* s& T6 z$ l* I( y$ f% g' g* m7 Q, k
然后编译执行就可以了(*^_^*)0 X9 C7 B$ N6 |6 w( h  E
其它:TC++上一定编译错误,不保证在VC6上也能通过编译. Z" ~+ u) Z! u& S8 n. c4 t
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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