返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
9 ^$ K5 T+ ?9 C! W一个很方便的函数模板,可以并且只可以计算含括号的四则表达式$ G* R) W/ k6 k6 \' H/ ?7 O( T+ {
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)# N* C3 t4 B* ^4 C, J, R
参数解释:
2 B3 E- y, R0 i0 E0 [istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
  ?& V' }* d+ u% e  [nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
- X* ?+ `' f. Z# L5 x  R返回值:
/ I1 N! e6 _' G; I/ k返回非0表示计算成功,0表示计算失败有错误6 Z$ B) @/ I6 n  |# v

9 f7 B, |' ]/ |$ R; T. C2 |% s " q& ]# c5 L& q. e% R2 W  e

$ w2 {) x  N6 V  i程序代码: 9 Y7 j9 ~7 z$ c. E6 r" L7 e- Q
7 s+ r% \4 G, k1 O. B# V
namespace fy_Exp{2 p2 a9 |& h8 ?* o2 |; G- M& q( T
namespace {template <class _T>
4 ~2 y$ i! m% N* O( t( O2 F: sinline _T GetExpValue(_T t[], char& csym){1 E9 D6 w, Y2 p) C- S. s% S
    char c=csym; csym=0;
6 B- j3 F" I. t' k- f    switch(c){
: J: F& e; D) T5 u    case '+':return t[0] += t[1];; g- L: @- x' f% O4 o8 S, N
    case '-':return t[0] -= t[1];& l6 z; S( a) Q& N
    case '*':return t[0] *= t[1];) }% o0 I, H% b: |1 x( Y; B
    default: return t[0] /= t[1];//case '/':7 {* e. y& q, L4 i
    }
1 x1 Q! D' M2 C9 F, G}}3 m! z, Y' @$ g
template <class _T, class _Tstream>
' r; t$ ?$ f6 J5 G: N/* _Tstream: inputstream, _T: get return value
" ~! p; y7 w4 N( L1 C8 G/ B* Return nonzero if get value successfully */1 x7 G# I  K& b' M
int GetExpValue(_Tstream& istrin, _T& nReturn){( Y4 ]9 g1 x6 U* Q* g- r0 R7 F/ Q7 g
    _T t[3] = {0}; //雨中飞燕之作
5 }5 `" a4 e2 t    char csym[3] = "++";+ {! O9 \& D9 n0 ?; G0 ^5 M
    int nLevel = 1, nERR = 0;
! O6 I8 R5 L, h) r    if(!(istrin>>t[1]))istrin.clear();2 ^3 L2 ^, K& U( |: Z
    for(;;){
- O, z0 d. u% R* V# r! }        if(istrin>>csym[2]){
- `1 {6 A3 \+ k/ x' t            switch(csym[2]){
1 ^/ i. @1 w- k' Z6 ~7 h            case '(':2 {2 g3 O( l! X1 d' ]
                if(!csym[1]){nLevel=0x100; nERR=1;}else( P, d% X  E# W
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;3 l8 c: |0 j- Y9 `3 O! a1 @
                else{nLevel=0x100; nERR=1;}+ ^; ?) U; A' W
                break;. w6 A. a& q: [" M# x% ?# P# \. b/ {
            case ')':
* n: Q/ ?9 r1 O# v& }' R                {nLevel = 0x100;}break;2 D3 b9 ?" H: x  U9 i& ]
            case '+':case '-':case '*':case '/':6 i$ Z: k7 J5 J& H. K* H6 j+ J
                {csym[nLevel++] = csym[2];}break;* a! @" T- `7 }7 }/ L
            case ' ':case '\r':case '\n':case '\t':continue;
0 e- ^5 I; e3 L            default:* ?! O9 Y" Z, T% b3 G. a: Z( a
                {nLevel=0x100; nERR=1;}
0 y. [7 L' j: A7 o            }# b1 h4 @$ K( X; I) c5 U- w+ ?
            if(nLevel==0x100)break;
+ k& N1 I3 C7 _% J+ z$ S3 C            if(nLevel&0x10 || istrin>>t[2]){2 f  ^9 \- x1 U* Y5 K
                nLevel &= 0xF;
: Z8 i% V7 A2 s7 {                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}* a3 q$ Q/ P) n8 _7 z# y- }
                if(csym[1]=='*'||csym[1]=='/'){% i5 ]$ T7 p- M5 e( B
                    GetExpValue(t+1, csym[1]);
9 }' A7 K% S" W6 V                }
+ ?$ G! R9 P  r6 b                else{$ O) D# |7 U. J+ i$ k/ P! R7 Q, Y& j# t
                    GetExpValue(t, csym[0]);
* u6 L+ y) Y7 V/ l) x                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
. E- |4 C* R& Y% q1 h                }
6 e' h6 v- _6 V' y' Q9 U0 M                nLevel = 1;; b- ?1 N) x4 a; W& U
            }
: @8 W8 l4 Y- p2 W& i# O            else istrin.clear();) d+ D  }9 |$ j- N6 A. @
        }$ Q1 A! w( I6 T' s: \
        else{nERR = -1; break;}# x' S# i; ?- A7 O( `4 J3 q
    }: M* T& r' s* }, s1 `9 ~+ Z
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
1 p/ F* k& F" |" M9 L" s5 z- O% v' C1 N    else nReturn=GetExpValue(t, csym[0]);
% _4 e$ j; R+ G2 S9 p    return nERR==-1?1:0;) r5 _+ A5 G6 W  @& x
}}5 ~" r& Q! V3 v: b. J5 W/ N
/ o$ d" Q/ Y/ {& J/ t

/ s$ x( w; Y7 Q. e" A) M1 c' f7 M, Z5 T& T
函数模板使用示例:( N# v% ~& n# i, R5 p
在以上那段代码的后面加上以下代码:
5 h0 x" s7 \2 }* Z! c' |( F2 z
, |8 m. J+ \; h 9 K/ w% G& G' j$ q
) M4 j8 W, U( a) D' N  Z
程序代码:
8 {: Z  T  G( ^6 Y
1 Z8 m5 |  c) b" Z% s+ o$ U#include<strstream>4 x! ~4 O1 I- L; l- o8 N- O
#include<iostream>' m7 R( c1 V+ a1 h. A$ H, M
#include<string>& {# w. n6 C; p* a3 A/ M
using namespace std;
- P: \6 b; o1 Hint main(void)/ ]1 Y9 w! X" q+ W
{( H  b! D4 a& \$ P4 G; p% i
    string s1;3 Z  B5 B& U% K' `% ]7 ^; F% X
    while(cin>>s1)
8 K0 i3 f2 `, y    {
" n) T9 s) v& z5 [7 i" z        istrstream isin(s1.data());. V0 x# Y! }; w( I# h! N
        double d;4 t5 B; R" D  n' I0 A0 t4 y# G9 p
        if(fy_Exp::GetExpValue(isin, d))% Z* I2 c9 w5 u$ w( x
        {
+ j. T  L3 u( H, O- t8 W( j. X            cout<<d<<endl;
1 _: z4 s6 R0 [: Y        }
6 Y6 [& l1 F3 }3 ]7 R0 J  `6 y        else
" Z0 c4 g& b! A. X  r" }0 X        {
8 q8 l& w1 e1 ?- V9 x5 }/ j            cout<<"ERROR"<<endl;  ~% P) p" u. B/ R& g/ }& T4 R
        }
8 a8 D# }% J/ i9 F( k2 H    }7 \& x4 y) W& ]+ c- O/ e
    return 0;$ o* e: J2 O' P. o- n) b
}0 N0 {' A! c: F( s) g

  l2 {$ L( t4 t9 O/ C7 ^' n2 B. F- q- l5 [5 t# r
然后编译执行就可以了(*^_^*)) b9 F! _/ j* W; ]  N# n+ V: p
其它:TC++上一定编译错误,不保证在VC6上也能通过编译
$ W, U9 o& I4 i$ K/ J      建议使用VC7或VC更高版本,或者使用GNU C++编译

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