返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,$ d1 E0 @/ Z/ m1 z4 W5 F
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
5 v% ]7 D+ k" M' B  S只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)1 O1 |2 O0 L6 X: \( [
参数解释:2 M: A* K( n1 N
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流( @, ?$ V; [' d: w6 b# K
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定( v& w+ ^! a) R7 I0 R9 q9 [
返回值:
$ {% v: C2 `0 }, m返回非0表示计算成功,0表示计算失败有错误
! c4 n- G9 M' Z4 A. u- I
$ `# x1 F( j* W' J4 k! s0 L ' V( y( Q3 w! C
! z/ [9 U* F3 L3 h7 [  j: |
程序代码:
% M/ I2 x7 f) d+ c# A0 I4 N4 @! t, d; C/ x% A$ q
namespace fy_Exp{# @& _$ m5 X$ h$ y
namespace {template <class _T>0 I* B1 s: H5 E0 _/ n
inline _T GetExpValue(_T t[], char& csym){
. g; S' ]. `$ a    char c=csym; csym=0;$ `" `- D3 C" s1 u% ?0 T2 v( ?9 Z
    switch(c){6 S6 [: _& L- {9 m
    case '+':return t[0] += t[1];
: f6 W+ {) Q3 _8 T0 L* V    case '-':return t[0] -= t[1];
$ g0 X, @. c+ z  z+ R    case '*':return t[0] *= t[1];
, J1 P* o( _" c! \5 t1 J+ A# J0 i    default: return t[0] /= t[1];//case '/':
1 w0 i4 r" A' H; c; @    }
* O, a. C" L( f9 q}}
/ P0 `7 @* O# C; J& `template <class _T, class _Tstream>
5 Q! t% ?" \$ c/* _Tstream: inputstream, _T: get return value# G! D; ^* q, v- H5 ^* O: ~
* Return nonzero if get value successfully */# k9 \1 U: J. b" ]- e
int GetExpValue(_Tstream& istrin, _T& nReturn){9 t; j8 E9 K5 n- n2 \9 K
    _T t[3] = {0}; //雨中飞燕之作
9 n4 v2 t7 h/ S5 T' ~    char csym[3] = "++";# b# M# i, V. O# x8 m9 C
    int nLevel = 1, nERR = 0;9 p4 \* ^* B( ^, h! n
    if(!(istrin>>t[1]))istrin.clear();
2 X5 Q3 e6 N8 H& }5 M    for(;;){
4 S' @4 V1 N$ `" _        if(istrin>>csym[2]){
, f! P9 p4 l' c( U$ O& k            switch(csym[2]){
# f' F) R  I, e  H! [( {            case '(':1 A) x6 y! v5 t
                if(!csym[1]){nLevel=0x100; nERR=1;}else) H8 x" w! c! N
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
3 M5 g1 T0 j. f0 Z                else{nLevel=0x100; nERR=1;}
' R$ C2 n$ \( w2 ?/ v                break;
9 I- c" G$ X$ j& d% h            case ')':
2 c+ Y6 d$ o; F7 U3 ]. u, k                {nLevel = 0x100;}break;) x# S" {* G+ t& x" M
            case '+':case '-':case '*':case '/':4 r3 }8 b- B% m+ d, d: A) d
                {csym[nLevel++] = csym[2];}break;% I9 n: p4 x/ q. h$ a
            case ' ':case '\r':case '\n':case '\t':continue;2 d0 ]3 H; M5 l, a0 l, `
            default:5 r; ?% L' k! \0 X% k8 i0 Q
                {nLevel=0x100; nERR=1;}% u8 T, i6 @# R; E% C; r% c" R
            }
9 C0 d# T; U2 c# T1 N            if(nLevel==0x100)break;
: @" {9 o. `. S, Z2 v            if(nLevel&0x10 || istrin>>t[2]){
' d4 O* m% ]7 w) L5 N+ l                nLevel &= 0xF;3 ^2 m' Q5 A3 B$ f+ @4 i
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
  Q0 U' g1 r: r! O                if(csym[1]=='*'||csym[1]=='/'){4 I# h0 \8 ?3 d
                    GetExpValue(t+1, csym[1]);( M+ A0 e2 s* i3 R6 o
                }
! g! q2 k8 B- ~. @                else{
! Q, [3 q) U, f2 ~                    GetExpValue(t, csym[0]);' c7 t8 t; h/ [0 {1 F
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;3 y1 _* E# J! ?8 ?8 O; I1 H
                }* q" x. G; `* W
                nLevel = 1;7 \1 M, S& C' E1 B! }6 c
            }
0 ~' j) y7 E* U            else istrin.clear();
  f$ H9 l" e* V; J        }5 ?9 j# z  {2 k% B' [  |# @
        else{nERR = -1; break;}
. O3 c6 l! i2 i0 l$ e" q3 c8 i; r$ z    }! m5 v& ^' k: S) Y+ y9 {7 q( g
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
" B8 E- C0 t: ~- ~& K    else nReturn=GetExpValue(t, csym[0]);6 J; M" L/ i  Y5 }  q
    return nERR==-1?1:0;
9 Z7 J4 j7 v7 |}}
* ]# v( x" v3 C; ?
$ p6 ]3 m+ @- Q3 M- u0 z1 U- |# {& ]* S; v& q

9 f& M4 S; M" D函数模板使用示例:( W2 L4 t4 e* X; Z1 e: b1 G
在以上那段代码的后面加上以下代码:
2 \7 D- y0 m- ]7 F( L
9 ]* O2 i% J' p" p# g# A2 h# P' {
+ V9 m! ~" S8 P" a
/ Q2 W5 O+ T& |/ A9 u- U, y4 k程序代码:   O& P9 ^5 v* R+ R$ t/ H
3 T' W0 o' d  k3 K4 r4 n
#include<strstream>
$ }1 |( q* A9 Q9 `/ t#include<iostream>! {% I2 }8 A4 j* y4 \
#include<string>/ O0 ?8 k8 o$ r6 C1 I- C
using namespace std;
8 T5 d0 P1 m- gint main(void)0 l" o9 N4 d0 s( D0 g3 X+ h
{) ~& Y3 [: b/ O; @: k$ i
    string s1;% F4 x1 W0 D# S/ u+ b9 r6 `
    while(cin>>s1)
7 K' k) @& r0 g8 \( V+ ^1 H& p4 H    {. }/ N& i% Y; L# `2 X! Z) O
        istrstream isin(s1.data());  l% b+ D' J3 A) b" a
        double d;9 B& E- v) v" I! x0 @1 Q
        if(fy_Exp::GetExpValue(isin, d))& i+ y6 m4 }; ?" n0 |: Z
        {
1 T; o! ~4 X% ~) W            cout<<d<<endl;6 b4 j( V/ s, ~7 A0 v) k0 d! \
        }
* C' K% [( B% D& x' h        else
' W& t9 A* f7 H: s        {
' h- v1 J5 W% p: M7 H) c# |/ R            cout<<"ERROR"<<endl;
# l% S$ ~0 B; c- U, o1 {        }% W, @1 _) }) i7 C" A
    }7 m3 j6 j' v* G% Z1 h% |& ^" Z2 L
    return 0;
8 Z, o+ x) s8 c' Q}$ y( L4 a+ R+ C  O& H0 x. u8 |1 P# n

1 t& v8 F" g; @& j+ g
: L' b  g$ o6 F! p$ c然后编译执行就可以了(*^_^*)0 c7 C. n% J; s" \& \6 ]
其它:TC++上一定编译错误,不保证在VC6上也能通过编译; ]+ A; s; G% ]
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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