返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
# O' A6 i  m+ O; A" h, E* z( w一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
9 {+ V# @: Y7 i4 y只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)+ M- ~4 p0 @3 L$ I$ q' {; p
参数解释:+ w6 D4 N. K$ U- F% r  T: z# |
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
7 C2 ]3 E; s! cnReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
$ P' E5 e& _7 F( k5 e# i! |, D) a返回值:+ x6 F: [. g8 N" ^
返回非0表示计算成功,0表示计算失败有错误5 M2 B$ n! r0 D0 ~  P' ]6 k( d
9 L, r9 c; B( L& c! C
3 T7 x' G4 D  @( s3 u
  N( ~3 f- x. \* S+ n
程序代码:
. y2 S% x& c2 b" N* v
7 @: b' N5 Q2 ?' k2 F* A- ]' Fnamespace fy_Exp{
& |) y  R3 a- s( bnamespace {template <class _T>6 [, g/ A+ l+ o8 U- |& q7 v
inline _T GetExpValue(_T t[], char& csym){
( a: F. m6 v7 f; W4 r; M    char c=csym; csym=0;, a% Z% o' x( R
    switch(c){) a: s( E$ P$ Q
    case '+':return t[0] += t[1];
5 Y- o- l# t7 \    case '-':return t[0] -= t[1];
7 S  {  u3 ?0 a+ F3 [* X    case '*':return t[0] *= t[1];
6 r: s2 @' U' U. R& }8 K    default: return t[0] /= t[1];//case '/':7 V- l7 C( Z6 Q
    }
. R9 b* V7 D$ w( ]) E% T}}' X% \6 C1 l; I; ]& t% ^
template <class _T, class _Tstream>
) H" O$ c) f$ g; G0 n/* _Tstream: inputstream, _T: get return value6 ~1 B& ~% o5 y! t
* Return nonzero if get value successfully */) f' h* I* A/ c& w2 j- j
int GetExpValue(_Tstream& istrin, _T& nReturn){( m! D; o8 G+ M  V1 Z( ~; J6 {1 q
    _T t[3] = {0}; //雨中飞燕之作1 M: h2 U$ _- K( E  }) B+ r" V
    char csym[3] = "++";
4 k1 z: g4 \( }- ~' @3 s/ J& K2 g    int nLevel = 1, nERR = 0;
. ?  U- ~6 e6 v, V9 n; {    if(!(istrin>>t[1]))istrin.clear();
% I& `! X8 _7 P( z/ X  B2 v. ^    for(;;){
5 F3 S% L/ _: U* r% L        if(istrin>>csym[2]){
4 D; c+ q' H: J' Z) O; T/ b            switch(csym[2]){
& E; b; F+ g7 x' ]  C" P            case '(':, k. P3 `1 h- u2 y" F
                if(!csym[1]){nLevel=0x100; nERR=1;}else
( h; L& r' A4 p1 U3 K4 T. D. O+ U                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
- T% m2 r9 k  [1 M5 L                else{nLevel=0x100; nERR=1;}3 d& Y; D/ Z6 u& z, V! I! d: ^& z
                break;& |$ P# j+ ^; d7 N( y3 x- B
            case ')':
* W  s( Q  J, \* E  Z& s5 g                {nLevel = 0x100;}break;3 P7 Z3 L' D/ D. {6 M! T" M
            case '+':case '-':case '*':case '/':
! z- H5 c9 J8 w: L4 F5 e- l0 \+ k7 ?$ E                {csym[nLevel++] = csym[2];}break;
! D/ d1 T7 `  V9 @9 i) @            case ' ':case '\r':case '\n':case '\t':continue;7 @" t; z4 T2 Q
            default:; Q( N- K1 A9 N: i, w' j* D
                {nLevel=0x100; nERR=1;}
9 E2 B; q. e; d# I: i1 Z$ s& x            }
( M! F* E5 @5 h9 B  F            if(nLevel==0x100)break;
7 a# ?( J0 P4 i) y1 Z. m            if(nLevel&0x10 || istrin>>t[2]){
- i# Z) G. M9 U3 Q# I/ X7 e# J                nLevel &= 0xF;
8 r* P- T! Q& T& G% Y                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}8 W) W% Y. I9 O; @2 p6 P. S
                if(csym[1]=='*'||csym[1]=='/'){
) P) o6 O. [5 `% ~  o                    GetExpValue(t+1, csym[1]);  {; Y' q0 R+ x2 h+ q+ F2 j2 W
                }$ E7 X4 D$ A3 {
                else{% v9 s. s+ w8 c; d
                    GetExpValue(t, csym[0]);0 p( m$ G! t4 M; P6 M: m1 P
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
% k1 D" [! v& W                }
+ H5 D# k+ M( j; g* c# q0 p) }                nLevel = 1;
) y) ?# o1 U% z7 L( U+ x% z! S            }. Z2 e, p. n% z# R9 I
            else istrin.clear();9 q" s' }- p- {" k1 t3 E" ]$ O' g
        }! i# d3 ?- x9 q( S
        else{nERR = -1; break;}0 ~) L  x% `& v8 l( O
    }
6 R1 y6 H/ f2 c    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
+ R  N  G% v/ J+ ^: o' ^' Y# |    else nReturn=GetExpValue(t, csym[0]);
  {  a$ o% o: [: x! r    return nERR==-1?1:0;
. n1 G6 F5 l( e0 j3 Q& {" W}}6 R2 p# \& F; \6 J) \
! }, M+ O( H7 m  H( n  r
- i" f2 R& L9 q
& f. M3 x; A$ E
函数模板使用示例:$ E9 T! w! G% z; v4 |. y
在以上那段代码的后面加上以下代码:7 U; S4 K" o+ ]% O2 b6 B) O

9 j& B- b6 n* J: F* _1 u 1 N$ w5 ]& l$ \; c  r, k: v3 x- m3 J

- [* X8 g- A! p! m程序代码:
- R) }- o& j' s4 r9 x/ J
7 o6 p" r/ b4 |+ ^+ H8 G#include<strstream>8 r: d' f" U2 g& S: b8 W# ]3 S
#include<iostream>
8 j* v  b9 R, c3 z* e9 \#include<string>
4 x2 t+ s! k7 N( O8 `% V& N8 W- ausing namespace std;) g: H) C1 j, a8 R3 E8 `5 ^  F
int main(void)5 e4 q# f4 {0 {9 C9 g$ e
{
# Z$ B8 ~$ i  m# Z& k% x    string s1;
0 f0 q9 e( v9 O; `, F0 i    while(cin>>s1)
* H3 C) F* Z# Z+ m    {
3 B! n  i* y  y0 w; O; [! m        istrstream isin(s1.data());2 M  s3 s8 _( ^! A0 M4 C% j$ O
        double d;
, Z/ f  R+ J' H% U5 ]/ b* v        if(fy_Exp::GetExpValue(isin, d))/ ^+ B  f3 W( k
        {
2 \: p& W0 O! I1 ~: |& p: g            cout<<d<<endl;8 n: [: m- d% I0 O' `
        }
/ x, ?( ?: _9 k$ U! o7 j6 t        else6 r- ?/ @6 \  U
        {: H/ Q+ m3 S7 P+ s) ]  w( Y
            cout<<"ERROR"<<endl;6 m* o$ Z3 q8 a/ U
        }
- ^  j! x+ F( W( j# Y1 s2 w" B    }0 O0 ^* Z0 H) l0 B& h1 c8 r+ x
    return 0;: R; a$ @4 g, J. I# K
}% e. N: T1 V* d7 M. C4 h  h0 m

0 H0 f& G" I2 B- C" ?8 L! a9 I# B; [, M2 k# m
然后编译执行就可以了(*^_^*)9 Y6 N% Q9 F6 \/ Z. w* l$ p( Q
其它:TC++上一定编译错误,不保证在VC6上也能通过编译
& r$ c5 M! T+ k, y/ p! c      建议使用VC7或VC更高版本,或者使用GNU C++编译

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