返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
5 S/ H* T5 L+ ?5 U' s  H一个很方便的函数模板,可以并且只可以计算含括号的四则表达式$ n; l! S! L/ J: r' P
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
8 c! ?* q, q/ W参数解释:) |* C; h7 Q( m8 G: n! e4 c
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流! i: h+ ~- Z3 w7 y' m
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定, F" e" J: g) b( {: l
返回值:
5 [6 F& }: @& i# a3 j+ m# ?. {返回非0表示计算成功,0表示计算失败有错误
+ y" Z( ]9 p, D$ c( A7 W& a* ]
0 j+ E( j/ h  J! T- T% |5 v
+ ~9 ]9 f/ d( d$ w9 K( c. ~& e: \( J8 @; m2 P( Z( D
程序代码:
8 F  }( w6 i3 G7 I+ D
5 R5 |8 U6 n' a2 I! y' O$ r% Snamespace fy_Exp{7 M! [/ z) I0 Q1 v
namespace {template <class _T>) G* d4 h- F! ^9 c! ?$ k
inline _T GetExpValue(_T t[], char& csym){
8 I! c$ q# d/ a7 w  w% }) `7 Q9 v    char c=csym; csym=0;, [6 x$ g! p' B- L. b+ o
    switch(c){
! V  Q" T& k" V" Y' J    case '+':return t[0] += t[1];
, P$ z) B" s. Y  k6 T8 r$ _, |    case '-':return t[0] -= t[1];
8 S* c0 y* ?- k/ F8 I; v    case '*':return t[0] *= t[1];
$ J  M1 C! B( w  [1 X    default: return t[0] /= t[1];//case '/':
! C8 K# e* B: f: Q    }
& ]3 a& `  S* h+ X}}! e( n- u; {: m4 F: D6 S" P
template <class _T, class _Tstream>% i/ H' `5 Y( ?# k8 R( r
/* _Tstream: inputstream, _T: get return value
1 _: \, {- s0 }  w2 l# W% B* L* Return nonzero if get value successfully */, \) X! j" a+ o3 T
int GetExpValue(_Tstream& istrin, _T& nReturn){
) W( g1 N$ S6 J4 v* a    _T t[3] = {0}; //雨中飞燕之作9 u+ {& {; m, e0 `6 }/ v, x  U
    char csym[3] = "++";
7 O7 m+ d& L7 E' g" T; ]* _! f    int nLevel = 1, nERR = 0;
1 I" O4 Y! W8 C" X/ k7 d    if(!(istrin>>t[1]))istrin.clear();
) ?) T  p4 {: T+ j$ t/ K. \) ^' m    for(;;){
, a7 _1 K) Y# [5 f) I% f$ Q        if(istrin>>csym[2]){
8 @8 ]  y$ P9 Q3 a" W! n            switch(csym[2]){
; F* w6 B9 A  {7 a8 I/ m9 y- D& _            case '(':
0 c% X; _  k% b6 e                if(!csym[1]){nLevel=0x100; nERR=1;}else' A0 c1 P) U$ g3 ^* h' o: x" n0 N
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
" e% [  L% S, j7 M  M8 D2 I  E" ^& `                else{nLevel=0x100; nERR=1;}
2 y4 ~5 L- T8 y8 K0 k                break;
: q; m+ u/ \, y7 Z* U            case ')':3 }% k0 i0 G% m: l. D4 K
                {nLevel = 0x100;}break;
. l9 Q2 x( {3 ~* ~. I, @9 e1 s            case '+':case '-':case '*':case '/':
6 m2 ?, m$ Y3 s+ I+ l+ D                {csym[nLevel++] = csym[2];}break;
' J9 x8 `3 L: j! {4 D# S. z            case ' ':case '\r':case '\n':case '\t':continue;7 x, s) _0 j. [: x
            default:0 }# ]: x/ {7 B: o) ^$ l3 h6 b
                {nLevel=0x100; nERR=1;}
) J9 a: a8 w5 l            }
) C% U; y" D* V" G            if(nLevel==0x100)break;
2 A5 N! @" O& K% ^            if(nLevel&0x10 || istrin>>t[2]){6 B/ {7 k1 Y6 s8 l, O
                nLevel &= 0xF;
7 G5 v- S) D, I! t' z! Q2 L                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
' F) `4 Z9 F7 c+ c1 M) T                if(csym[1]=='*'||csym[1]=='/'){* |8 `* H% Q5 d3 s) A$ r# Y' }# Q
                    GetExpValue(t+1, csym[1]);
# A  ^$ g7 |3 \, d6 q                }) [$ _) E/ s2 o! T/ E( l! T
                else{& d- s$ d( b* g5 C( N8 u6 Q
                    GetExpValue(t, csym[0]);6 S2 l. d. m7 q4 S9 k5 f9 R/ r4 f& Q
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;; |; ~- ~' \  ^$ W
                }
: f7 s& k6 G! i4 U% B: t                nLevel = 1;
5 Z! K; u* l3 \            }
# v- _% ^' k+ R- R% m            else istrin.clear();4 P: K, Z, j) J: F2 ]% ~, ?
        }8 z5 x8 C& ]( e5 e9 W0 V0 d, ]
        else{nERR = -1; break;}1 N5 z8 @& _" x- U* z; m
    }
8 d" w! _$ `' ?: ~, g    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);$ E( O! J" ~' N/ A! _
    else nReturn=GetExpValue(t, csym[0]);+ [/ i# g# ?+ v9 p
    return nERR==-1?1:0;
. U" ]( c* p- b7 u9 F}}
7 b% B0 @+ f) M! x
) J, M9 w+ }9 _, x  R; X  v7 {: R5 v5 m$ K: |( I3 Y

: g5 e9 z5 P' y9 r! X  H) q% W函数模板使用示例:
' `5 W: u& I6 Z* z在以上那段代码的后面加上以下代码:
/ N8 H' J7 K5 B
+ C4 ^  F% s8 ]5 M! e( g % ]  s( n8 b: C3 }7 J$ M. n
7 l2 v* X7 [4 D
程序代码: - X+ d( ~  g4 C' I8 a
5 r. Y; L% R7 j2 i
#include<strstream>
! b/ X' K6 M% M#include<iostream>. r% K5 x* I+ o+ _
#include<string>" U8 }: j) P' J& U$ j
using namespace std;* g  A/ n9 I$ j3 [
int main(void)* j+ K0 D, `: H2 i
{7 K) D; e7 B0 P/ G7 I
    string s1;. B  i( T4 N6 Y2 ]; q- G0 Y- l* {9 l
    while(cin>>s1)0 {! j+ r  S' ~, v1 u
    {
2 e6 p+ f' \* M! c: J% v8 v        istrstream isin(s1.data());0 U" Y+ v+ b8 _, d; Q
        double d;+ x* t% i$ l2 G5 ?% l
        if(fy_Exp::GetExpValue(isin, d))  x( D+ M# y5 g4 z& }! Q4 X, `8 A
        {
3 Q9 w5 [. Z) g$ ?. [            cout<<d<<endl;
. j, j0 `; n3 b' e. W        }
6 q! P7 J* {/ O7 t, S5 ^% t' R        else3 Q$ j2 _" v. b- `
        {
9 H6 x# E2 l- _; H- k' _/ ~            cout<<"ERROR"<<endl;
6 ~( w" I$ p/ g7 K1 j: C        }; L' K+ R$ H3 N$ b. H, f7 _
    }
9 f+ h( D; {+ ]+ l; O+ F& \    return 0;
% \& V* L+ V' {7 w: r% l" z}
8 X5 F% R+ ]% x6 a+ U* K
6 C# H3 t7 b0 O0 U" y$ R- s2 Y7 g, ^( X  _4 a: P
然后编译执行就可以了(*^_^*)2 U! \. F/ m' P' R9 E4 Z+ Z0 G
其它:TC++上一定编译错误,不保证在VC6上也能通过编译+ b# @/ ^$ {5 Y8 \" \
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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