获得本站免费赞助空间请点这里
返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
( I( k% E4 I) s' Q# X3 ~7 C  v一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
  t/ {  R7 Q5 R. K) }  M2 Q只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)6 q- B2 Q: J' _# o7 \
参数解释:# {' a0 X( H4 ^( J
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流! T( Z7 y) w5 e* A0 h- N
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
7 ]/ [% R" f- {9 Z$ Y  a; I返回值:
9 B$ F0 }0 J+ G: T返回非0表示计算成功,0表示计算失败有错误
& T2 z8 U% V2 V
3 K& v) t8 O2 E9 y6 ^4 t2 L+ B, ^ - v' J' s3 N# W- {- H

1 N. T2 [* W. B程序代码:   B0 E6 |% r/ j" L- m
. x' L3 l- M3 V
namespace fy_Exp{% z7 y  u: s, r! j) _) ]) i. d
namespace {template <class _T>
' m$ |" Z6 W# e* O  L; Tinline _T GetExpValue(_T t[], char& csym){
" i1 f1 L' i& L    char c=csym; csym=0;3 e9 a7 g# j, O
    switch(c){
' k, x* y; w) T/ E    case '+':return t[0] += t[1];6 ]. H9 K" `& a  {- S, y4 {
    case '-':return t[0] -= t[1];
+ C1 r" }: l4 G' R3 B    case '*':return t[0] *= t[1];
% O3 z/ S  t9 n$ o: j% @/ }    default: return t[0] /= t[1];//case '/':
6 ^6 k' G0 K4 \9 T  A    }* o# ]0 F5 p; d! L2 O  E
}}
8 Y7 H+ g; n- \( g$ A3 ~3 ]template <class _T, class _Tstream>
/ c6 R/ ~) A2 h  }/ y5 x/* _Tstream: inputstream, _T: get return value3 W4 v8 o/ Z$ q+ v
* Return nonzero if get value successfully */
, u9 v% \, R7 z, [8 tint GetExpValue(_Tstream& istrin, _T& nReturn){
. U( u! k+ p& L; J  q& d    _T t[3] = {0}; //雨中飞燕之作- h8 _$ z7 T5 \
    char csym[3] = "++";4 P" J1 D- |: H/ t3 ?
    int nLevel = 1, nERR = 0;! h  i5 ]$ X- \# u; `
    if(!(istrin>>t[1]))istrin.clear();5 p# \: n7 \  {0 k! ?& }/ ?3 Q
    for(;;){
3 X4 |* \, C( P2 ]8 U( |        if(istrin>>csym[2]){
. \  x( K( Q: A+ C0 e- K8 A) C            switch(csym[2]){
" d: l0 O1 g0 S8 `! w            case '(':, V  [8 c7 E) ]/ W4 c/ \
                if(!csym[1]){nLevel=0x100; nERR=1;}else5 v' v( |7 B8 J& w
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
! \# V* V4 }( c' F( v& E                else{nLevel=0x100; nERR=1;}1 e: ]2 N4 y- t0 D; q
                break;
/ I, h$ c5 c( q( d! o" s. Q            case ')':" p' e- W# ~0 T6 B
                {nLevel = 0x100;}break;! u7 T1 ^0 T8 E+ {+ b9 S3 ]
            case '+':case '-':case '*':case '/':
: n5 [, o5 S! T/ w# f. D' @, a                {csym[nLevel++] = csym[2];}break;
3 l$ }& U( Y# R  }- E            case ' ':case '\r':case '\n':case '\t':continue;" |4 S- D( Q+ w
            default:/ `# y( ]7 \  _( e. l
                {nLevel=0x100; nERR=1;}$ C1 n* j& V8 J5 {5 C1 `& f# `( B8 [
            }
: ?- G( ?( W4 B  Z7 ~- D/ W            if(nLevel==0x100)break;0 L, I9 v7 ~' h/ h5 V3 i; K
            if(nLevel&0x10 || istrin>>t[2]){
2 I: @7 e* [: U0 `                nLevel &= 0xF;: G- L4 ^# O( \% y8 |
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}, m" Q  `# w2 A# o( {
                if(csym[1]=='*'||csym[1]=='/'){3 `8 Z  O6 I) E9 l  a  y
                    GetExpValue(t+1, csym[1]);
# {3 i+ Y/ J+ V) I. X4 E5 l' h4 {& S                }
% _- X2 p- N3 [8 o                else{
2 B1 P  @. J% E( J& q7 r                    GetExpValue(t, csym[0]);
6 y9 d5 r& T3 t0 M5 l                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
8 f3 l" \0 `( O                }3 n( H  n- e; K' z4 m
                nLevel = 1;
" Y! I+ I# ~  n, z6 S- P4 K            }, b, t% l6 k% H
            else istrin.clear();' C5 k! p; a( ?1 s$ Z9 f# h0 l
        }- e3 j4 r. r0 f3 Y, s7 B
        else{nERR = -1; break;}
- a5 G* P2 z2 r; j5 _; o& k$ W) k    }8 d5 H: z7 a: ~3 T" l1 W% ]
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
  s+ T" u0 ]8 {2 ]    else nReturn=GetExpValue(t, csym[0]);
3 n9 N. o6 {7 y' H% p* M    return nERR==-1?1:0;
3 L( B6 p4 v9 Y( t( s6 F}}, @# l, l  N$ }  x) J

5 `# u0 A* b: O( B3 g2 V5 i! O
& L$ j* f0 J+ \  W$ @$ o) q
/ d, ~* O2 i' e, P0 {# U; @函数模板使用示例:
" D% p: x/ V. O( Z- D" K% z在以上那段代码的后面加上以下代码:
3 c3 F. D1 C8 C5 d% f3 y& N" A+ ^/ h6 C- a/ P" a( }! Z) x- f3 B

' d+ S4 l) Q8 g0 |0 c/ s/ Z# w% b. ?, J, P
程序代码:
9 B- @! W% _% W7 U! u/ [. B, C# ?- R( q
#include<strstream>
5 b7 y/ |" R  f% B) o4 `6 |. c#include<iostream>, ?2 |1 ^, ~5 g& l" ^, M
#include<string>
4 I: x( e  S; g. j- _5 Lusing namespace std;$ \. f$ q7 o, Z0 D  L( u1 h3 l' T7 J
int main(void)
. B# ?; _" \1 Q/ ^# C4 b{
( P" b, D3 K8 ?: b$ D( `    string s1;
# j+ n! Q9 _; u, N$ \, W; ?    while(cin>>s1)4 ^( w# }' X+ _3 h- L
    {0 W, f4 C0 }4 T8 x
        istrstream isin(s1.data());
5 S: A! e/ g' e, v# Z        double d;* d, f" }' {3 r* l( I8 r6 n
        if(fy_Exp::GetExpValue(isin, d))
# `: Z: t/ L8 X" I        {7 l' }7 w9 V: O; r" ], ?( E, O  {
            cout<<d<<endl;
4 z  g& V5 k" z" N5 D, f        }0 ]7 m0 p3 z: Z0 e0 [
        else
0 s. a. y% ^$ a+ p( S( o3 w) r        {5 D+ s) G% l3 R+ V# k1 n# N
            cout<<"ERROR"<<endl;" ~9 u1 q* n" k' q3 W# W
        }$ K0 m" s' H* w
    }
9 D! g  a6 w- \1 x5 h    return 0;
' t1 e$ M. B" a5 G6 i4 U3 K* r}1 N$ V/ z" q' k% U/ e3 f

" l8 H7 U9 m1 v3 a8 c! y" q/ K) x2 R; l
然后编译执行就可以了(*^_^*)& j* R+ e9 I( K: B( i* ~
其它:TC++上一定编译错误,不保证在VC6上也能通过编译) H: Q) X( F9 n) h1 H& v
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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