返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,! }/ S" t1 K8 r3 [- o: t8 j
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
7 [& O( y; h8 b$ o0 S5 a只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)& ~7 U( i' b* a' {
参数解释:" H+ t6 Z& h7 d7 D  t5 G
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流3 Q" N/ s' C) V2 v; U" W5 O
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
/ P) p% y, s& G% C返回值:
7 t9 O0 k- ~) R$ y, x* q返回非0表示计算成功,0表示计算失败有错误
: n6 b, c- k6 q( {1 D% {2 h7 ?* U
6 Y. |: y. i5 C2 {8 z5 _7 ?; F 4 E7 B. K5 q, y+ @5 n0 n1 G6 k$ w

9 P1 Z% k5 v2 i0 R0 a程序代码:
& `. f' ?  p  D$ U& F& V. o3 `; v" C. W& U
namespace fy_Exp{+ R' t- z2 j- k2 k& r9 S  ^1 C: z
namespace {template <class _T>
5 e6 A+ G* R; }; ~inline _T GetExpValue(_T t[], char& csym){
* w! U4 U6 W! |    char c=csym; csym=0;
- F! j" u) a/ q' w  [    switch(c){$ g1 a& ?/ p8 H/ p. j. y
    case '+':return t[0] += t[1];4 Q: w- ^) m* s: q& e: U! H7 Z
    case '-':return t[0] -= t[1];
6 ?( F/ t; _2 J/ w    case '*':return t[0] *= t[1];
1 [6 }6 y3 U$ }# c: h  r    default: return t[0] /= t[1];//case '/':
! d4 ^) z' I( E$ m" [, \! }  V5 X. p    }
4 d5 d! ]& a% t3 l}}
* W2 s# j6 B& {$ l; t) etemplate <class _T, class _Tstream>: }# k& K2 f( f5 K. O% V2 o% n
/* _Tstream: inputstream, _T: get return value$ [" t& b1 p% ]6 T
* Return nonzero if get value successfully */
  l" a7 g. i* G- f. S$ M+ Y* gint GetExpValue(_Tstream& istrin, _T& nReturn){; O" S: E" e  {' c. [; }$ o- E0 y
    _T t[3] = {0}; //雨中飞燕之作
  v/ w' b# N& z. c' g    char csym[3] = "++";0 V* B2 I; @4 q
    int nLevel = 1, nERR = 0;
3 {. u# n& A$ X2 L  R2 i  g$ |    if(!(istrin>>t[1]))istrin.clear();( w' n/ c7 o. O
    for(;;){( J1 r0 y- `6 T% F
        if(istrin>>csym[2]){
% k- x/ e- Q  Z            switch(csym[2]){( I( R. u2 l. d) I
            case '(':3 t( m) \2 ]3 y' O, C
                if(!csym[1]){nLevel=0x100; nERR=1;}else
% {& E5 H, @4 R/ _                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
& L% m- `4 L' ?% y                else{nLevel=0x100; nERR=1;}2 [: N! X/ G# m9 ^4 |
                break;
; s$ U3 `3 J  o3 r9 T  }            case ')':
0 H9 t' r  h& C. `8 x+ |                {nLevel = 0x100;}break;
8 h3 `+ K- t3 p, D0 ?! }+ W            case '+':case '-':case '*':case '/':
" L! k% K* ?( L2 _2 C                {csym[nLevel++] = csym[2];}break;
& n: R: q3 T. M' c/ I            case ' ':case '\r':case '\n':case '\t':continue;4 |) D8 S7 \5 [+ |
            default:
" B3 ~+ R6 R' \4 [! M                {nLevel=0x100; nERR=1;}: d1 E, n( I* Q$ P6 U; x8 p
            }& [2 c( X( J  f  N
            if(nLevel==0x100)break;
4 R4 ^) k- t( i  I8 W            if(nLevel&0x10 || istrin>>t[2]){% {' [+ S5 I) n0 p) K  S: ^
                nLevel &= 0xF;7 c7 O9 {* B1 R8 ~
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}. n+ I! U( T4 ?4 ], S% Q- v/ ^
                if(csym[1]=='*'||csym[1]=='/'){
  K5 i! J# p2 }                    GetExpValue(t+1, csym[1]);+ V# x; y7 g% s; R( F
                }3 {& E7 l  E* ?0 ~, L' t0 }. v
                else{9 H# t. s- t# p! P
                    GetExpValue(t, csym[0]);% C- }! J, m3 _: W
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;2 H! o" w" x  f3 I' f% w1 C
                }* i, ]- G  b3 s. ^% M( u
                nLevel = 1;5 A  o; A8 @, @! W5 c
            }
3 e3 C$ `1 I3 q# ?% Y* I            else istrin.clear();
8 K/ E  [1 ?: [2 D2 Y& X1 X        }4 \2 D( s$ }$ Q6 U
        else{nERR = -1; break;}
$ q7 z+ o+ Q. D, O( b1 T( |    }
* C, z3 k; a0 c0 V9 D6 l    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);: ^2 R8 K2 Q" _# V/ w* {( ]6 l3 A) z- e
    else nReturn=GetExpValue(t, csym[0]);
0 Q' N4 B6 S% @    return nERR==-1?1:0;% N/ Q0 H' r$ z& x% f
}}
! R6 D8 |) q1 q& l3 X) M+ [; o% v- p1 S: I2 g% g" d% I
' \0 s8 X% q! y8 z( O  c

, I" k2 H: ^; |: ^函数模板使用示例:
8 P/ i8 `* d4 n7 H9 K在以上那段代码的后面加上以下代码:
( u: W$ _% o. I/ ~% C, X0 c3 j
( K- {) j0 ~! i( N% V9 H
4 b& C4 k  g2 o+ N2 K8 p8 i) b2 [' S( b9 |4 D+ f0 M/ X8 a6 x  K
程序代码: # s0 j; ^3 X( `  M% J8 g# Y
8 w3 j6 l5 l8 Z  f6 b# H; z
#include<strstream>: I: `5 x/ x6 a! ?
#include<iostream>3 J; M1 s3 M+ U$ R& U4 z
#include<string>4 b' u+ M0 ^1 @
using namespace std;
0 G+ i: X% w- W, o8 l! g" D* ~" Lint main(void)# l# _, m3 V9 u4 b4 W; e
{
& i. E3 x! C# P; w    string s1;
8 o* I: |8 M$ ?: ^8 w) Q! k& l4 r* e/ }9 I    while(cin>>s1)
) L1 f3 O7 L. |    {* ?2 o! P# z# N6 X9 @, O5 e
        istrstream isin(s1.data());5 v& |- [, B2 I+ q) K. @6 {
        double d;& J; p0 l/ G# |( l
        if(fy_Exp::GetExpValue(isin, d))
0 V/ d  v6 t. ^: F" |4 ?1 I8 G8 \. @        {2 F' h$ O: Z& L! A/ L( ~; Z( ]
            cout<<d<<endl;! @) R% c: y1 Y7 ?0 V1 D5 L! L
        }
, `; u; F: ~/ W* ^( }  `( ?  Z        else0 E( x- h5 G. ]. K3 G
        {( w  H4 y4 Q9 C, G
            cout<<"ERROR"<<endl;
1 ~; ]" i$ F, k* h& c$ I        }1 t& B" n! A4 O. _8 m5 l
    }5 k1 \1 {6 K/ O& }+ @  `
    return 0;  T' V* }" Z+ ^+ M" n8 J2 Z3 |& k
}4 z  ?* M( z& w  n1 \7 H- E

, w1 G+ k3 V: h& i$ [5 h- U( L: |# [
然后编译执行就可以了(*^_^*)
. y3 M& r4 x0 Z: ?$ z7 q% {其它:TC++上一定编译错误,不保证在VC6上也能通过编译
+ O: C5 ^% }: `* j      建议使用VC7或VC更高版本,或者使用GNU C++编译

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