返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,- q# D& I$ i' ~( i, p* s3 I
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
9 v9 x0 d5 X1 @. U% F, c5 H只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
7 U4 q& v% n2 K( G% Z参数解释:
+ i" o4 f1 W7 gistrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
/ S/ k; h3 a: r$ n5 e3 m& xnReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
2 D) i8 v/ r1 W) T/ b; v  k8 j返回值:
1 y& I  z$ ]+ v; l返回非0表示计算成功,0表示计算失败有错误0 v- ^3 M2 b% s: u) G

+ A; c" T9 ~# J% @* r 7 S- {! A7 d$ q0 [* M1 z- S$ m

+ x$ Y/ q! w6 }) d' ~6 B9 |' c: T程序代码: 6 V# c3 s- A8 s1 o! U/ h
2 Y, V; d4 ]) q9 @# J$ y$ _) Z
namespace fy_Exp{' @  I1 N. N+ }4 {; `' k
namespace {template <class _T>
) D- ?$ e$ E7 x3 S7 W. G, D9 ~inline _T GetExpValue(_T t[], char& csym){
7 t7 u  i  @, S0 f2 R% h    char c=csym; csym=0;
# @, n* f7 ^* O# i8 t- N    switch(c){
% m8 I. p( k. m% d7 f    case '+':return t[0] += t[1];
& ]. |1 O: d- h3 h9 O    case '-':return t[0] -= t[1];
' D" \. S/ Y! M- i' {    case '*':return t[0] *= t[1];
, [5 J5 a3 c4 k2 @" F    default: return t[0] /= t[1];//case '/':) \* J: S" V6 _4 C
    }2 s2 L4 W* K. r
}}* Y8 `5 S8 w% y
template <class _T, class _Tstream>
  g* p" h1 Y, j. z" T" b- G$ s8 A/* _Tstream: inputstream, _T: get return value: P* E) _% P7 B0 z& F4 ^
* Return nonzero if get value successfully */
6 I, e0 [3 R& Q. e" h) dint GetExpValue(_Tstream& istrin, _T& nReturn){
) I$ k2 M' a0 c$ B/ Y% r$ O    _T t[3] = {0}; //雨中飞燕之作
% I4 U  S! g4 {* t5 L    char csym[3] = "++";
8 I7 w, G4 o3 X1 D5 D    int nLevel = 1, nERR = 0;
3 g5 I6 w6 V3 i4 W* I% h    if(!(istrin>>t[1]))istrin.clear();
1 o0 U0 _! W( Y  e. ~( B9 D$ |, D; m    for(;;){
7 D. u" [" t& A' K3 w7 i+ a" f        if(istrin>>csym[2]){
- t; ~% j# @/ \0 e9 V! ]8 ]* ]: A  I            switch(csym[2]){3 \# n1 X. |( E! M
            case '(':' u2 z" t( j3 V' ]- V2 U. C& C
                if(!csym[1]){nLevel=0x100; nERR=1;}else7 ^0 ^) I0 ]4 r4 i6 A
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;* ~4 _. r! `6 ?9 _6 i# j
                else{nLevel=0x100; nERR=1;}- q5 }6 x9 }- k+ H5 s7 P5 ~2 ]
                break;0 g# W' [7 A/ n3 `/ o
            case ')':9 X" ?, p% A9 z4 E- Y' [
                {nLevel = 0x100;}break;7 ?5 S0 x3 L0 E- r- p
            case '+':case '-':case '*':case '/':
" m: f( y, a8 y  H3 j/ A' \4 M                {csym[nLevel++] = csym[2];}break;
9 I3 Y1 o3 f! @            case ' ':case '\r':case '\n':case '\t':continue;. u( L! Q+ I9 j) X7 ~
            default:
7 J- L! r# }! o6 c; X! _                {nLevel=0x100; nERR=1;}
6 I( ^  D' `( o+ p3 A- T6 W" n8 F; a            }
& ~; ^: C- P0 _! q  X            if(nLevel==0x100)break;, B- Q8 L. U/ @: v! @9 H0 [, P1 I% a3 h
            if(nLevel&0x10 || istrin>>t[2]){
* ?" |1 f4 E" @% r                nLevel &= 0xF;8 ~8 t, k) p6 l* z0 _" |; g  S
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}$ @; h) {/ }6 O) N5 ?; m6 r
                if(csym[1]=='*'||csym[1]=='/'){
# U# H6 H4 g1 M" E2 b                    GetExpValue(t+1, csym[1]);7 X  f& U- F5 _: z- \9 ~0 h/ |% i4 M
                }
' t$ a2 t: O5 ]% N0 ^6 K2 T- F                else{, ~( C6 G+ m+ h% A. S
                    GetExpValue(t, csym[0]);3 [8 g) ]$ D4 N6 c6 H$ `3 S( E& L9 o
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
# K* D% Z! W+ a                }
' x3 F/ \+ X' O: b, d; ~7 N                nLevel = 1;0 G8 d8 h- U7 }- E5 Y9 z! U& o
            }1 l+ z0 y* y" Y0 h
            else istrin.clear();
. J7 l/ {2 N) ^' p        }
5 H( [% a2 n6 B        else{nERR = -1; break;}
, I4 y, P8 k- A  b, F/ [* p$ V& ]    }7 ]/ |, k3 b5 _& z3 a2 _" C/ ]
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
' U5 |+ {! {5 L! j" f+ ?* |0 a    else nReturn=GetExpValue(t, csym[0]);7 A- R; o- K2 i8 B) }
    return nERR==-1?1:0;1 o' G; p" L. j8 R( T5 q3 ~8 S" q6 N: y
}}
* @2 J7 v5 v: ]
' x" i0 u, {* X: S1 {, W/ L4 F+ ^' m  F* e
/ Y. @  p2 }( B( @* D$ `& U/ H) u7 R
函数模板使用示例:8 {/ c9 E) E8 T7 r4 U6 z
在以上那段代码的后面加上以下代码:5 m. {' A; h- f' J5 s7 N
3 m1 J! Q" h# Z5 j1 M
  n8 H& n: ^0 k, z, V0 f0 u7 L
5 d  y& N" Q1 a. h# T; }; Z
程序代码:
4 `# U9 h  F0 t, C0 l& y+ D
! ?) U  D! S8 b; i, R4 a6 v#include<strstream>: T: P$ \6 {9 T+ h
#include<iostream>
+ u# ]+ a, Y: I( }$ f4 |) p#include<string># }7 ~* W9 h: n2 H( ~
using namespace std;
/ a" L9 U2 O8 ]4 I4 O  b$ _9 P/ Sint main(void)5 p2 W/ e) v+ |: ]6 }% W5 W4 ]* m
{) E* R; p' x2 d9 ~
    string s1;
$ h8 Q' m5 T2 v8 C  D3 X% o    while(cin>>s1)
) {3 U8 ^" S1 p$ s$ c7 H    {$ R6 V7 d9 w: P& c2 |0 Y
        istrstream isin(s1.data());- v' B7 K# v5 p
        double d;
2 ]# f8 M* i# z  y: K9 Y        if(fy_Exp::GetExpValue(isin, d))" Z/ J# K3 G4 e) O4 S
        {, b/ W+ e4 d! R% x. s
            cout<<d<<endl;
7 m3 \2 O7 b9 k0 O% M% d: a/ n0 U        }
! F; O  J8 |. o: ^+ @4 W        else/ b% ^# ~) }: w7 K( E/ s" p6 U
        {/ Z( q7 ]9 |  ?7 W
            cout<<"ERROR"<<endl;( ]! ?0 F5 S4 K. H! G
        }
5 e' r) M. |) }5 l+ D9 g7 a0 T    }
; G& s& b; s' L    return 0;
8 F5 x% k1 E& y9 ?9 C5 H}3 Q# h& g5 x# z0 `- Y2 J- ~

8 Q$ y$ C& L. J3 n6 H" [9 m- h& O: M, ?* {$ ]" @. t; Z3 Z* E. D9 _
然后编译执行就可以了(*^_^*)/ y. M. r" H% a  l- F
其它:TC++上一定编译错误,不保证在VC6上也能通过编译
# Z4 S9 q& G+ E3 A: B: s, P      建议使用VC7或VC更高版本,或者使用GNU C++编译

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