捌玖网络工作室's Archiver

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

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

在9月8日那天我特意编写的,给大家分享的,
(uf\6cyy 一个很方便的函数模板,可以并且只可以计算含括号的四则表达式UQ xheK&K
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
KZ8jD;sF5u B4?8b} 参数解释:U$C#M6D_sVL
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流[u;_x)?5{"]r{
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
E2s'F`,VPks 返回值:.[-dy d4G
返回非0表示计算成功,0表示计算失败有错误
tA}+M7RU4R"[
N_q,g'i-IvR^u
$N-~d[}_Y,VH ~$VUM1B|h
程序代码:
m&j*j QG&O
}PE(HOb N sj namespace fy_Exp{
B _ I G|u4v6H namespace {template <class _T>
mO7H1d!G inline _T GetExpValue(_T t[], char& csym){9uQT9JlN)}
    char c=csym; csym=0;
E'^n^HyH     switch(c){4h2[+B)\LU+~i:z
    case '+':return t[0] += t[1];
7g `5\lg$m7v!E*Ub     case '-':return t[0] -= t[1];%f$[9h ~;z)N
    case '*':return t[0] *= t[1];2v~(m t6s-b4i`6A8DK7|
    default: return t[0] /= t[1];//case '/':Au.R7cT7ndp ?6k9j#C
    }
3S6?:^!zQC }}
5[-KW}2J$N;T template <class _T, class _Tstream>
n0Ptu/mv3j:n[-{4`$d"g /* _Tstream: inputstream, _T: get return value
e$p ZgX*r4M * Return nonzero if get value successfully */\)y@x wv1}+~
int GetExpValue(_Tstream& istrin, _T& nReturn){
jk,J)xm/ixH     _T t[3] = {0}; //雨中飞燕之作
-xUq V5\h"y4UV     char csym[3] = "++";!p$Q0uw@ {~
    int nLevel = 1, nERR = 0;
E5J r.x k | r$i/L     if(!(istrin>>t[1]))istrin.clear();
[7N9C ^.[P3dd }     for(;;){
"@Uq~$T#B         if(istrin>>csym[2]){
a[ _N$n&C&{T9S             switch(csym[2]){
qe1H| t"|S             case '(':
Ze)z |E6Qu                 if(!csym[1]){nLevel=0x100; nERR=1;}else
c R2d6?r Q-N                 if(!GetExpValue(istrin, t[2]))nLevel|=0x10;(Bp.M:b N^J
                else{nLevel=0x100; nERR=1;}C9p0w%`#O#}&B)tT
                break;9P+GF!SW4h#|N
            case ')':)f:C4A.@2DB.`9gtp
                {nLevel = 0x100;}break;S7u0m(V\%r0h%c;Z t
            case '+':case '-':case '*':case '/':-a D&?%D u@:Cx
                {csym[nLevel++] = csym[2];}break;
.V:D;]}@_DNY`5]k(v^             case ' ':case '\r':case '\n':case '\t':continue;
[/i/gM+o-m             default:Sci5Y.h,h y
                {nLevel=0x100; nERR=1;}
m@IWK*bK             }j/_w%N;z-e
            if(nLevel==0x100)break;
4I7N:J/F#ab)aG             if(nLevel&0x10 || istrin>>t[2]){
k.oe!Brna p(K6m:JI                 nLevel &= 0xF;7C)`^{'WY%e
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
4Di:F5A r2nQ1I                 if(csym[1]=='*'||csym[1]=='/'){|.S]7r y7jq
                    GetExpValue(t+1, csym[1]);~!W [ ezAN*t3|
                }-Ljg3@)D8b
                else{7jy.J:AHxy
                    GetExpValue(t, csym[0]);
]'W"pp3N3he@                     t[1]=t[2];csym[0]=csym[1];csym[1]=0;
Px%D(u$?,O                 }
P1K1E NC^                 nLevel = 1;6nB;wq'g
            }v(K}y#Q:pD|j.X)T5c
            else istrin.clear();/iP-YS9rIv%T9[R.s
        }
._3c7^`(iB-HH         else{nERR = -1; break;}
v W e3N;F     }+Cd0j!Y*R6[f}1N
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);5D_ se+?Om
    else nReturn=GetExpValue(t, csym[0]);
a9c {MdA     return nERR==-1?1:0;
o Cl&@'}Fw1~5r%p }}
7x#\k;y~4@,x h$}y? -v$k'P0q]RL
XxLK8j
*y3zc+XO-E
函数模板使用示例:gk$},vKJ
在以上那段代码的后面加上以下代码: PlL eV9?'e~~'V
coN?D*i"l(t!n]

#j'U*e^.kxs"X hB Df+P N9h5{U
程序代码: O EFG?{ EVk I3c"?
&b/J/z7OOb9o5D$e6e&n
#include<strstream> OwD2H0S]uK
#include<iostream>
)cuq5xGS[At)c #include<string>6d4Fn7GS oNK
using namespace std; JY{;i&Gr-td
int main(void)
-bL ~ Bq5?%F2I,C"DU {
2Y$D!zov2V0l     string s1; T,z}/\~T
    while(cin>>s1)
xFd4y&Pw XB     {
A~6GzZQ6m         istrstream isin(s1.data());#KUN(J:dnk
        double d;
{1N-`VB T%\ U~p^         if(fy_Exp::GetExpValue(isin, d)) Tr0wz Z `
        {S2KZx ghI%e
            cout<<d<<endl;
Wnk]X8d9^?L         }
eP#f5|!OYH e         else
#HPOW:eD"R%m         {
\{$cvk7y;U             cout<<"ERROR"<<endl;
^ Cj7E l*\*k         }?#Q8O(IrK
    }
#{/gY}#I5T4v     return 0;+t;vygA h)Z
}I:L2TizT

3CR`0Y [&n0]3^:_
?y_-qF)w7k,Q5L:G 然后编译执行就可以了(*^_^*)
bW2dp+C!C.xT 其它:TC++上一定编译错误,不保证在VC6上也能通过编译
CW-RM&O-h7n^       建议使用VC7或VC更高版本,或者使用GNU C++编译

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


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