捌玖网络工作室's Archiver

zw2004 发表于 2008-1-21 20:17

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

在9月8日那天我特意编写的,给大家分享的,4_%~?)cFEj
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式^V1_&i\'M"j ~p
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)M-l [:H+lr8[w
参数解释:8w x&L9tq
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
4Nr4q8i~ zL%KP nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定ef uj&k1ZU+j
返回值:
|'l5ot/y6@j)sl.C 返回非0表示计算成功,0表示计算失败有错误
/EJ0^+y2y g-uAs3g&i

;WoF^B/u2|
4b3V[2}*oEz!FA 程序代码: :~q(EXY-P
Kr4oB(s&A k M]
namespace fy_Exp{)Lp$ER)cX
namespace {template <class _T> P#I5o$F7q
inline _T GetExpValue(_T t[], char& csym){
.a:g]`'q'I#@     char c=csym; csym=0;
3|4C6Vor0Dc     switch(c){Yur*l*gnA
    case '+':return t[0] += t[1];`0x5w4T%uVYG7]
    case '-':return t[0] -= t[1];
!X/Le nfX     case '*':return t[0] *= t[1];
7d+yWKl@lr(``     default: return t[0] /= t[1];//case '/':
(pn8?%cf     }
g5vU7ja{ }}
#R0vEN1a(RA1y template <class _T, class _Tstream>
Fd)x'phEL{ /* _Tstream: inputstream, _T: get return valueb? ^9VTn'P/AQW @
* Return nonzero if get value successfully */Bc4O5k:l|r#mJ
int GetExpValue(_Tstream& istrin, _T& nReturn){uij.Z9[
    _T t[3] = {0}; //雨中飞燕之作
Cv|.m dvO     char csym[3] = "++";
"a+}go+uR9cd)WL     int nLevel = 1, nERR = 0;2}7W1@3`)^C
    if(!(istrin>>t[1]))istrin.clear();
p E EiD P8M"f%O     for(;;){
XSvl:Q$r(`'w {G         if(istrin>>csym[2]){B#i b]&B;z E0`w
            switch(csym[2]){C,G(_ N]:i
            case '(':
h/[G*Gz.[Y(~Z                 if(!csym[1]){nLevel=0x100; nERR=1;}else,LYQ;o9CD
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
i'{*I'eh(G HH QW v                 else{nLevel=0x100; nERR=1;}
.C;W;@0M HOM(}                 break;Z)^O4Pk"F_ ?5u'] v
            case ')':wt"\!l(R*uY'xp
                {nLevel = 0x100;}break;O\ q:i3Q0n s(u
            case '+':case '-':case '*':case '/':
3^zH4n kFM`                 {csym[nLevel++] = csym[2];}break;
9kY y!a.VR)]             case ' ':case '\r':case '\n':case '\t':continue; r%|m6t }.r w/W8_
            default:
N&z m0|Uw8O                 {nLevel=0x100; nERR=1;}
I |)B S(AFj1\lV             }
*uT IF2~(|8kHiE             if(nLevel==0x100)break;'v,@&p3Y e8D6e0A0E
            if(nLevel&0x10 || istrin>>t[2]){4Q7U%f4rWuEs3z
                nLevel &= 0xF;
9MP~ I%?i+M?                 if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
x;C4T)d1Ic*\                 if(csym[1]=='*'||csym[1]=='/'){
I ^o1g5c1^+b\;o                     GetExpValue(t+1, csym[1]);
)k3v-J4U(]T#`S Fl                 } uN,Egq\
                else{)g-]TS_}
                    GetExpValue(t, csym[0]);
(B6Bj W1A/l                     t[1]=t[2];csym[0]=csym[1];csym[1]=0;W I5DD_+sl
                }K7v^pQ W P-dd
                nLevel = 1;!K5h.W5W8DC*O-F$K*wB
            }
7KjK3EQAT             else istrin.clear();
8g wo2}L`m0K"h ~         }@&B9dQ O|G1r
        else{nERR = -1; break;}v6k \ J7z)k,D-OVG
    }E T#r DJ9E:gy
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);Vu/r'om Wf$fF;r4h
    else nReturn=GetExpValue(t, csym[0]);
e/DA_ |uM0Pj3R/`     return nERR==-1?1:0;
%I;w.`/[9Z S }}
I#p&}MmH
:vfg]2ILlB?8U
Q(~.U0e$xna"I-Fb RBsPH
函数模板使用示例:
Pd x3?gb c7p 在以上那段代码的后面加上以下代码:|-od i&T y5[:p
OelmYS,x

)X7R|1J"tK .K0B X-o%~
程序代码:
,rk\+pcr n,g3v L9~ki[b$j-?
#include<strstream>+dv"ja:XK EH!g
#include<iostream>
E2{d~'dm#bpPK #include<string>S5Z X `{-h W
using namespace std;'@4o2b Q7~uaH7|
int main(void)
S E3WE {;?)U {T5a;|s"N3}h1U
    string s1;
N ~.m7j,`g0}     while(cin>>s1)
.l;o f!['Z+D[ }     {/ltD L CKH$X
        istrstream isin(s1.data()); s.O\ R\.V\:j
        double d;
I+eYh9QBS4Y         if(fy_Exp::GetExpValue(isin, d))&Ir|X9I j:IHR'Cr&U
        {
||g"I5j(]f             cout<<d<<endl;
Y\+~0|/}+}jK#c9Sy         }
;G`-Jg!yS2SA         else
sU%qJU         {k3y3pN x)W}
            cout<<"ERROR"<<endl;
L6AHb3P$QaP         }
C/G6I? z8BYO     }X;u#M})t+E-U#W0E\
    return 0;
._u"bEUc }
#r z)sT#Hr8n` J ;~.]7f5O)[7l o R9Ti
[ES%g.t9r gJ_
然后编译执行就可以了(*^_^*)'`(F})r8pc5X
其它:TC++上一定编译错误,不保证在VC6上也能通过编译tXT8@9a2{ p0Z9z
      建议使用VC7或VC更高版本,或者使用GNU C++编译

页: [1]

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.