返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
# `; s$ b- J" e一个很方便的函数模板,可以并且只可以计算含括号的四则表达式0 |6 I  A  D7 M1 l* [& Q8 j
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)* U3 b0 v0 o0 k. p& P4 P  ]5 e1 S7 O
参数解释:
3 Q7 N. W$ {3 w" g2 Jistrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流8 D' X: D% f/ L
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定1 W- @: b) h0 v. N2 J
返回值:
5 S- t% \3 E. A2 L$ W5 A/ @) X- z/ h返回非0表示计算成功,0表示计算失败有错误% v( |2 n, z6 r/ y2 H4 _$ c
. z: @$ d8 U, _7 L2 T

/ Q0 Z, P( }# U
8 p7 ]/ }% U' u& x. I! B+ E7 E程序代码: * r5 X2 Z  ~! w

) }" _6 f: K  }namespace fy_Exp{9 E9 w/ x- T! J- Z6 J' S: z
namespace {template <class _T>
6 |2 [0 X; W2 X" @inline _T GetExpValue(_T t[], char& csym){7 j0 R- z, n7 `9 v( f
    char c=csym; csym=0;7 O1 \  o6 F6 B7 J
    switch(c){) f. h( p$ C. p0 b; U6 m
    case '+':return t[0] += t[1];6 C0 Y; G) ^8 n* }; x3 r
    case '-':return t[0] -= t[1];2 r7 ?  Y  F2 K1 Q; w
    case '*':return t[0] *= t[1];$ d+ ?6 _) m* r# j
    default: return t[0] /= t[1];//case '/':
3 O3 w5 D; I7 D/ u5 Z, I! r, b    }
' F+ t3 m. X8 U0 f! f% \8 X9 f% F}}3 W9 P2 Y$ e9 m( X" g; {
template <class _T, class _Tstream>5 [9 {9 t$ d# Z9 ~
/* _Tstream: inputstream, _T: get return value0 b- t) V$ J9 X/ j6 }
* Return nonzero if get value successfully */
, s* |7 `; ~" D, N6 D! ^int GetExpValue(_Tstream& istrin, _T& nReturn){- V( j* {( X% n- V9 R  r
    _T t[3] = {0}; //雨中飞燕之作
1 P4 [( I, }9 d    char csym[3] = "++";
% _7 h" b8 ]6 B, ?5 s" K- O    int nLevel = 1, nERR = 0;
* R5 X! V4 z0 ^: i+ p9 u- |( o4 F. J    if(!(istrin>>t[1]))istrin.clear();( d1 ~9 F6 l: h
    for(;;){
% o- z6 i) e& R        if(istrin>>csym[2]){2 J+ H+ n& W6 Z# n1 D: b% `; o
            switch(csym[2]){+ D& k$ u: L$ u2 d/ ?! e( n
            case '(':6 A" |5 p/ `3 o" t
                if(!csym[1]){nLevel=0x100; nERR=1;}else7 e) v' B4 a$ \3 A1 l  n/ }
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
0 E6 F( r, x9 l                else{nLevel=0x100; nERR=1;}
8 @7 f1 g, _2 p$ o" t                break;
0 x: P8 j* M+ z9 _8 n- l9 r            case ')':7 T# G0 T  ?2 q% \, L
                {nLevel = 0x100;}break;0 x. _# a: @+ ?$ h9 `5 _
            case '+':case '-':case '*':case '/':7 N) @0 f3 R% a+ [2 i6 _' W' K
                {csym[nLevel++] = csym[2];}break;3 n8 g2 t' t+ S0 I3 o/ |8 Y0 r
            case ' ':case '\r':case '\n':case '\t':continue;
& Y  I7 F% `  ]! f            default:
1 v3 I" x+ [+ A6 e* _# h4 y                {nLevel=0x100; nERR=1;}
4 U& D! p: S4 r- a0 y            }4 G" t- w1 P. H' {0 |/ C4 U
            if(nLevel==0x100)break;) G$ I$ @7 s# m: b' h7 c2 s
            if(nLevel&0x10 || istrin>>t[2]){
: j' Y7 ~! |/ {' T! U" t4 J( c                nLevel &= 0xF;
2 O! R; m+ o  s; J7 T- b                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
9 M. y2 D1 W' {+ v                if(csym[1]=='*'||csym[1]=='/'){0 E+ c1 @" {% ^" \
                    GetExpValue(t+1, csym[1]);
. e: L3 e; s6 Q  F4 [% i0 B                }9 F* |1 `& M2 }! a  b) b
                else{: J8 u8 k! P4 W  p! j: {
                    GetExpValue(t, csym[0]);% }4 a" ~  [7 Z2 u' A+ {/ l* l. [
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
: T" X7 [; n- G0 |+ Z8 }                }
* j/ D) L" \( P1 W9 t* h# R, a, f                nLevel = 1;3 J% L! {3 M4 x% |- Y5 N1 \5 B# {  F
            }$ `5 c% j1 z2 }7 \* @) V7 K2 m$ l7 l
            else istrin.clear();
# {5 ]4 \3 f: F  S: i! k        }
0 W7 n! s* |6 `* f! j        else{nERR = -1; break;}7 d% v, @2 {' n/ {' i! M
    }
$ k0 t8 ]! n1 W+ F    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
0 b; ~# N9 [7 R/ d! P( m    else nReturn=GetExpValue(t, csym[0]);! D& W$ C8 f# I. N" p+ S
    return nERR==-1?1:0;
8 T1 _1 o2 D# U1 D}}- s$ H2 y8 {: X) U% L5 p

, _( r1 {5 z/ l; O  x2 w" Q' B0 E9 z4 c/ V; C% C0 x2 C, c/ t

) z  M/ C; z( b' M函数模板使用示例:
- a( N& Z5 U' L$ e  A在以上那段代码的后面加上以下代码:
. v  ~% D' G5 D8 O( ^
* B3 H& Z5 a# C- k) f( J, Z
& x. e+ z4 c0 q. y" l4 _; P6 F; T4 u' |, q( w' I& D0 q
程序代码:
% y. J+ b' K! O% n; F! Q
- ]! ]/ K+ d6 p, [2 T; a#include<strstream>- z5 O$ d$ B. e
#include<iostream>- H# v+ [/ _; k; |
#include<string>$ C' e0 v0 T+ D  D8 N3 |9 d7 w
using namespace std;# X: Q7 F& |1 s2 T' P
int main(void)
7 y6 U" S7 l8 r/ a( G" v* `2 |' c0 _0 K{
# D0 g* ~5 V1 S$ L# N5 D    string s1;1 G. H1 W7 Y" r! |% j. ]$ u3 M
    while(cin>>s1)
& [& b/ ]0 W8 u% j3 C; u    {+ \; H1 ?: O: u  O
        istrstream isin(s1.data());
% Q3 P* k/ p/ Y2 E9 h        double d;+ {4 ?. z! E. ^, o: w: U  n
        if(fy_Exp::GetExpValue(isin, d))
' L4 N. O6 L4 L0 C9 w: b7 K) U        {5 ]" o# d6 U8 b; O2 h% }
            cout<<d<<endl;
/ \! Q! k+ b8 {! P% ~, }        }) J- K' P0 m% _% b' D
        else& o. s& k! t+ ^* ~- Y) ^+ G/ H7 g/ w+ Z
        {
/ x4 ~$ A; V* W, O, e; M            cout<<"ERROR"<<endl;
+ ?& A1 g' Z: Z  `2 A' J( T. I        }) K6 J  ^; P, R9 q1 c# d" `+ r1 W
    }
* f& ?" I, R8 g  |0 i! R, D    return 0;
+ I$ ~3 ~7 L) e7 N}9 p6 [7 X# }; \6 g" {, T+ C
# \" V* g* z4 _6 y+ x, _; i

8 f6 h2 j+ g6 o- \1 t2 w9 |然后编译执行就可以了(*^_^*)
! B5 t7 G, G' e# W; D& c1 I, @( _其它:TC++上一定编译错误,不保证在VC6上也能通过编译
& n; l9 d+ e& E- ^5 z1 G( H      建议使用VC7或VC更高版本,或者使用GNU C++编译

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