Board logo

标题: 一个计算四则表达式的模板 [打印本页]

作者: zw2004    时间: 2008-1-21 20:17     标题: 一个计算四则表达式的模板

在9月8日那天我特意编写的,给大家分享的,& C$ y' p( l0 o; ], F7 R- j
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式$ G, k; W. I% ~- ~8 d
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
3 d$ y/ K- h, B参数解释:
& P+ ?. {. z) R9 V6 listrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
  t$ I/ s; ]" _nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定9 k5 Q" g& a! U1 V# E
返回值:
  T1 c. K7 o4 e8 O' A2 r2 }7 Y* g' Y1 f返回非0表示计算成功,0表示计算失败有错误
0 I! L% f- u9 g. x) n( L
5 T* [, ^; W1 I& N. W- s, b
9 z. Q. x: t& h- z7 n( F* |* Z; C3 D
. ?. C; `  w' D9 @' `* T3 z% F: r程序代码:
3 _; Q1 Q2 s$ {$ P5 {2 ]! f0 c# n. z" ~* t2 m, u
namespace fy_Exp{- w8 W$ W0 t- d1 x8 ?/ u
namespace {template <class _T>
8 Z/ k+ F- B* z: A: uinline _T GetExpValue(_T t[], char& csym){
5 a4 q5 N5 E( b/ @" M/ }, X% Z6 _" q% {    char c=csym; csym=0;
( Q; W6 d/ G' p9 [" P  _    switch(c){
7 a* l4 c4 ~9 n' E    case '+':return t[0] += t[1];; U( F, s, Y# P7 F& W2 x: t1 b, g! D
    case '-':return t[0] -= t[1];0 l; q( \8 [% D0 x$ h+ O
    case '*':return t[0] *= t[1];
) V5 [( {: ~' ^8 y( Q    default: return t[0] /= t[1];//case '/':0 z* W( M; B5 u1 }' c% J3 s4 H/ z
    }4 X5 r, f( I: p+ f  ~
}}# @8 w* S3 ]: v% a. l5 {
template <class _T, class _Tstream>
* d. r* ^$ c( Y. Z/* _Tstream: inputstream, _T: get return value
+ y) B8 ~8 e2 R5 _0 U: p( ?$ B5 r* Return nonzero if get value successfully */$ D7 U2 y% X7 C1 k1 o
int GetExpValue(_Tstream& istrin, _T& nReturn){
9 X3 {1 M8 A( w9 F/ a7 U9 L: A    _T t[3] = {0}; //雨中飞燕之作
$ c! Z! l/ M+ |# L  {7 N    char csym[3] = "++";
" E$ d5 N# v. s! u: {! \    int nLevel = 1, nERR = 0;5 q8 N$ Q- b$ ]
    if(!(istrin>>t[1]))istrin.clear();
- i5 Z5 z) G' O, ]! g, d3 n    for(;;){( {6 f! m% ^9 F; n) Q
        if(istrin>>csym[2]){
5 a6 i2 T' ?/ l( u6 o: i0 ~            switch(csym[2]){, a2 w8 q# J* Q
            case '(':+ }1 p* {# ^6 M. F) v
                if(!csym[1]){nLevel=0x100; nERR=1;}else
" H* o0 r" }3 m% p0 Z4 k1 m                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;. j! \6 c$ j' k- [! S5 F$ I
                else{nLevel=0x100; nERR=1;}
# L% Q2 h" P) I- d; ?                break;! l% h( }2 b6 a3 M5 {/ [1 {
            case ')':; t& y" ~. f% ]/ n
                {nLevel = 0x100;}break;
1 ]# s& C' d6 f5 _9 K            case '+':case '-':case '*':case '/':
1 D2 o7 w1 ^& u' i                {csym[nLevel++] = csym[2];}break;4 u  |  s+ N3 ]  _! q& Y
            case ' ':case '\r':case '\n':case '\t':continue;
2 u! v, X+ L' V% U6 m# A$ t1 Y0 v            default:5 s2 b5 o* M2 j  P: _
                {nLevel=0x100; nERR=1;}' y: j+ [) N$ b% R, s( @" q8 {
            }
4 h; U8 l. o% Q6 |' w" I( D& G            if(nLevel==0x100)break;. N2 @7 x: h3 z
            if(nLevel&0x10 || istrin>>t[2]){
- Q& t' S+ r1 P9 v/ F                nLevel &= 0xF;& C* V9 d9 E$ G( h; E
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
% Z9 h$ b% `- L7 v                if(csym[1]=='*'||csym[1]=='/'){5 U# T/ |! Q9 J6 ?; L6 u1 `
                    GetExpValue(t+1, csym[1]);
! \; B/ U8 K8 M0 z                }
6 {+ m% j- Y8 d; ~  a6 F& H) C                else{
+ R# ~7 J9 p" Q/ h- i! X# T. `                    GetExpValue(t, csym[0]);* \" ?+ p$ y* c" Y
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
5 U$ K7 s, \, M                }0 g7 v. ~$ a9 w& I
                nLevel = 1;
8 h9 n) f: d& G  ~3 n            }
' z( H% @+ g  ~) w            else istrin.clear();
3 Q8 D0 F$ s/ I  o4 Y. t0 v) Z        }
: C5 x  w  v- }* H        else{nERR = -1; break;}
4 L  ^8 k3 ~, R- i# {2 F    }
1 I& u4 \4 x, D' l( {# S    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);9 G8 z% Y7 R5 [, S# {
    else nReturn=GetExpValue(t, csym[0]);
: s8 D& [; }2 ^8 C    return nERR==-1?1:0;
. V$ e# N" R; y, z2 v}}
2 v+ N& _/ C: z. J: }
  m- P1 w- [+ _1 h2 T: G: a
" O6 E% w# |$ J. N- o
+ {- I. |0 i& \函数模板使用示例:
( \4 u# G: m: U在以上那段代码的后面加上以下代码:/ i7 |% a4 I7 M

! f7 t" ]/ \# b  b% a0 D* c1 s 2 {+ U& d" O+ k$ g* |% o- m! O* r
( h1 A5 n6 V! M# Q
程序代码:
& Z% U: o+ f. S# B, {- s2 ~6 H5 |5 k$ n; b
#include<strstream>
3 e: s2 a/ v# A! v! J#include<iostream>! S0 b3 D$ S, \
#include<string>+ L. T3 V: B2 l4 p' s$ R3 V
using namespace std;
. T# `) d9 S  |( m+ tint main(void)% q5 h& \0 e, Z  ?* w
{
( W( B; G" _3 y1 M' D7 J2 o" _    string s1;
4 C! M' g5 {4 ]    while(cin>>s1)3 c$ ?+ ?% G2 ~& m" _- G' n: s
    {1 \: E  a6 s$ M
        istrstream isin(s1.data());) W# h0 D& q1 T- A. C  m0 \, n& X7 f2 d
        double d;* P7 I7 D) l  i5 R
        if(fy_Exp::GetExpValue(isin, d))7 H: l# F$ Y/ _8 s6 ]
        {. d/ f3 H; F5 O% D
            cout<<d<<endl;* V$ e. g* o$ u- s) z
        }
5 v7 ]" Z* p- m7 k( @+ O. X" @# o        else! a- G& b+ t& R0 k1 Z
        {
8 k2 e- Z; E* u* X6 y            cout<<"ERROR"<<endl;; [( W: t7 o9 I! v* S2 a1 R0 v
        }0 H1 u4 g$ h: B! f5 ?+ T0 {
    }
6 a. m+ @- l* s4 s0 f8 g    return 0;4 @7 e, ]+ d# A& D0 r( _& p
}$ a: y* C8 X- L9 r9 x0 e# l& B

$ ]" s4 C. X0 w5 f, b' O, |
& t" _6 v/ j. {8 [7 i) q  P6 c5 b. J. ~然后编译执行就可以了(*^_^*)! W; c; p8 ]: V2 ?2 d9 ^* g& |
其它:TC++上一定编译错误,不保证在VC6上也能通过编译7 F2 R. s* k" V4 p! O
      建议使用VC7或VC更高版本,或者使用GNU C++编译




欢迎光临 捌玖网络工作室 (http://www.89w.org/) Powered by Discuz! 7.2