捌玖网络工作室's Archiver

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

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

在9月8日那天我特意编写的,给大家分享的,sbsynk
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
Orj{!^^0i 只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
Zq+j5@!F 参数解释:.?,m sr!Du
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
I }%RdH g0d nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定:zN6Sc)zS2E
返回值:t,e:q%r5}A ~H7{
返回非0表示计算成功,0表示计算失败有错误
*Q*S*R%W7Y/DiJ
_%[(vrC!X Th^@ KCKhD"?-]

]U;y7t0p/h 程序代码:
]I)r&CI${O r z F \dL&U.U
namespace fy_Exp{
NA/a OtM+T namespace {template <class _T>
| ^+yu"I7A%da inline _T GetExpValue(_T t[], char& csym){+c qq3b*M2YM
    char c=csym; csym=0; G{"T!I3M
    switch(c){
b*mM.ug8G;])]1E d     case '+':return t[0] += t[1];]T*r+v6K8N,R
    case '-':return t[0] -= t[1];
X&fDc]c$KW     case '*':return t[0] *= t[1];
&qcI[X k     default: return t[0] /= t[1];//case '/':"t)t%Pd"?7h9p6i ug
    }
])iby:Zc }}C.I7x^uNp5q"|E*i
template <class _T, class _Tstream>
ca0N ?B1N { /* _Tstream: inputstream, _T: get return value%t/s+h8i@0g
* Return nonzero if get value successfully */!K G4T-ccIkN
int GetExpValue(_Tstream& istrin, _T& nReturn){[f\ Y4B/a.D0?
    _T t[3] = {0}; //雨中飞燕之作Y kVc!ml ^Y
    char csym[3] = "++";
#h#f4n Ad@O     int nLevel = 1, nERR = 0;
8vD;X+YL`1?9]     if(!(istrin>>t[1]))istrin.clear();Gb.qb_%I#C'_u
    for(;;){
6}H$egg} [s E         if(istrin>>csym[2]){
s@9?7b Ju;\             switch(csym[2]){
E:Q5E.ak!@@!w+W0Q$B             case '(':2B6dA+v ~R3gv ]8j
                if(!csym[1]){nLevel=0x100; nERR=1;}elseSE$mEgf`^
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;~H`F P(Hbh}
                else{nLevel=0x100; nERR=1;}
+Ap]\2],H T                 break;B X.g*z8V
            case ')':Z5[dT;H:y.\
                {nLevel = 0x100;}break;B$y&O:Sbb
            case '+':case '-':case '*':case '/':o:u6W`4h XY
                {csym[nLevel++] = csym[2];}break;kL;v7PS![En)[
            case ' ':case '\r':case '\n':case '\t':continue;
(i9f5c?4HS{aE             default: UCGI K-I#`4oN|&}
                {nLevel=0x100; nERR=1;}
&P{6_ae             }j|9k@(oDF)N
            if(nLevel==0x100)break;)@TDXb+CwS
            if(nLevel&0x10 || istrin>>t[2]){-pz ~!U\J
                nLevel &= 0xF;4v5L+LDL'W
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}7B4\*q(Y#B]x
                if(csym[1]=='*'||csym[1]=='/'){
#j-M p#^kYcN/U                     GetExpValue(t+1, csym[1]);3W'v-} l$Y"\Ip,g-?E
                }
L1g!a5m&\i%o/H5c"[&Sb                 else{
+J-Z$i`7E `EG8B"t3u                     GetExpValue(t, csym[0]); n.` Vc&@?9Hv)R ~X
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
YX e"r O9|%y                 }!M4|^T?BL9K
                nLevel = 1;
5b W h!FfPL ta l#o             }
T#^$kSx _F             else istrin.clear();
n%T?!FL         }
6thD E nFOm]         else{nERR = -1; break;}
#[z$r-X8b}pr     }
K"jqk$bu ]0Ed5u,o     if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]); p~_&a/D7S @
    else nReturn=GetExpValue(t, csym[0]);4c|dQa&F&[:S RF
    return nERR==-1?1:0;
0VvG:HA(@] }}
.Tv-p.r-gL*b w)?0C H {&|r3A
2l+c)s2H8Z,v'ue
_5wO3IGz Q
函数模板使用示例:
culZw5J 在以上那段代码的后面加上以下代码:
]c+jP3u p)P :b1n1S6t(? e

v nV)Mrf0Y y-C
h7Z;K&vj+b8u"HU 程序代码: )rwAx]mJ;v
;S+||l*\(Z+Ph/}*l r&|
#include<strstream>
!}-\ ~5b"O7JG #include<iostream>'vt-u9^(I)]
#include<string>n6KKlruC
using namespace std;3`#UM+MG n6ho(K[4k~
int main(void)
tB$r3`$FV$u6~ {4`*n%^WvW W __.t
    string s1;
@j [z w3x     while(cin>>s1)Z,sr:S)x*r#p;n
    {
e!N'pl)t1p1oJl         istrstream isin(s1.data());4_B~(\P7P+f
        double d;_} I.|0A g Q0K
        if(fy_Exp::GetExpValue(isin, d))
N:Z dIJ2P7H         { mxNyZ%F:XWw
            cout<<d<<endl;
k?7_&W!q%ov         })G8f/n$K6~1{,L ^+c
        else]N~e$yG,L_y0M
        {
cwY6h:t#u)M)~             cout<<"ERROR"<<endl;
#P;T3@ gC         }
Wl-H["C] YE R     }3S_ }!Vs3c#YY@a
    return 0;
b#U"UQv7D"? }\.N a sd2Z

sl!T4s `)t QJqPM_\
然后编译执行就可以了(*^_^*)QI3Z@ Xv
其它:TC++上一定编译错误,不保证在VC6上也能通过编译
3DC {6wxG/nb7Z#\       建议使用VC7或VC更高版本,或者使用GNU C++编译

页: [1]
【捌玖网络】已经运行:


Powered by Discuz! Archiver 7.2  © 2001-2009 Comsenz Inc.