返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,) j: c# H) K( R4 a# d
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式# \3 H" |0 z* p" I+ ^
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)$ Y  D, c5 a; [; e
参数解释:6 X# k  \- w" A$ d+ r
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流/ N' T5 H# G4 Z" S
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定# V8 u) P$ [: S3 E$ L) [5 w
返回值:2 ]+ k9 t. z9 v4 z
返回非0表示计算成功,0表示计算失败有错误
& r7 y  [3 c+ Y  r5 b2 k. r
7 C- I; O% S' q; w
, X/ i6 s! e0 J; A2 b2 K2 I
% H- I  z, Z8 v) L8 m! q# n程序代码:   _7 t' S1 ~. n1 D
% \2 G- k! X9 |7 x" u8 `0 t
namespace fy_Exp{5 b' g8 m: ^, A3 Q
namespace {template <class _T>2 ^" C% a! |1 {% ^; i
inline _T GetExpValue(_T t[], char& csym){
) F: h! z/ K' u    char c=csym; csym=0;1 _& k$ R& l) k" g
    switch(c){: H, o' a+ ~" V- r' K2 K3 g
    case '+':return t[0] += t[1];( t* |& k9 I) `9 ~+ c/ r; D
    case '-':return t[0] -= t[1];. _  c% Q9 Q0 d6 t
    case '*':return t[0] *= t[1];
# b# G( z( p! q! a# U5 u    default: return t[0] /= t[1];//case '/':5 W& Z0 n+ G+ J, v
    }
7 S$ X$ I9 Q1 R4 s4 P) R1 r8 i}}* a- S3 |+ g! \. A# r8 C. ~8 M
template <class _T, class _Tstream>/ k1 P' R3 R+ K8 B: f( g
/* _Tstream: inputstream, _T: get return value0 u" \2 @8 o$ X4 E
* Return nonzero if get value successfully */; v1 \0 P9 |, ^! b# p/ k
int GetExpValue(_Tstream& istrin, _T& nReturn){
+ w% _2 k# f# u$ C2 ]. J( M' A    _T t[3] = {0}; //雨中飞燕之作
8 [7 k3 g- A) ^9 A    char csym[3] = "++";% d. V+ F9 @. r( o. I- L: \
    int nLevel = 1, nERR = 0;
7 [% o% i4 N% }- u8 u    if(!(istrin>>t[1]))istrin.clear();: E) G+ S" \+ i; S5 f% b
    for(;;){
8 {# A0 |) m! `0 |1 y        if(istrin>>csym[2]){
" i. d" @7 m- l! G; M' h& h; f7 E: H            switch(csym[2]){
" ?# O. A5 q; F& U) I$ l            case '(':
1 ?- \4 J( K& J# F8 F9 S                if(!csym[1]){nLevel=0x100; nERR=1;}else' h8 |- s+ A4 {) p8 b$ y  A
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
; e0 ^0 n  [, @                else{nLevel=0x100; nERR=1;}2 l! G1 [3 K* X8 h) H2 n1 ]
                break;
0 O+ g& @( z: X  l8 t+ a; u            case ')':& r) ]. k* P0 F! ?4 `' H
                {nLevel = 0x100;}break;( v+ A! ~" l4 |0 t+ o
            case '+':case '-':case '*':case '/':
& e. o9 Q+ G5 h0 i, d3 \                {csym[nLevel++] = csym[2];}break;0 Q  P9 s4 U9 q2 D) V
            case ' ':case '\r':case '\n':case '\t':continue;( p5 v5 W. {  Q  l" `0 j
            default:' \0 }( C2 x. Q) x7 I
                {nLevel=0x100; nERR=1;}
# W& P( Q! I7 P            }+ K# Z- }$ W, y. d6 s
            if(nLevel==0x100)break;. j5 T4 T) [2 c" [/ m) E2 X
            if(nLevel&0x10 || istrin>>t[2]){
4 o) R" Q) P5 ?% f                nLevel &= 0xF;
  ~/ P3 D- b& {2 m+ z' v5 W1 `                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
+ T/ H1 M9 K' }; f9 Z: Z                if(csym[1]=='*'||csym[1]=='/'){; Z( B& d& Q8 G, ^' W# Z
                    GetExpValue(t+1, csym[1]);! L2 n4 }  Y' [1 d4 ]
                }4 T( q0 T) J. \/ m+ i, Q
                else{2 d' T& w# t# K9 y& n
                    GetExpValue(t, csym[0]);
; N0 H* B3 e/ h! @8 J: e                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
4 R' L5 l; Z  D, |                }
/ [" X* t5 U$ C# S- H                nLevel = 1;0 s" I; |- z) A- M+ _5 w
            }
6 _: ~5 R2 i9 W            else istrin.clear();7 @- V& J! y' T$ \5 X8 T
        }. a  z! K7 w8 q
        else{nERR = -1; break;}  e  C- V  H0 D
    }. T8 n  |! n! c  ~
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);. m! D  Z5 M9 |/ x
    else nReturn=GetExpValue(t, csym[0]);
0 Q1 \1 P; L( F* i1 ^1 ?$ @    return nERR==-1?1:0;" ~( b9 N! H0 l, j
}}' B6 I- l/ N( k' t% l' L
3 H: V1 E" n$ u' t

( }7 x9 y) D+ T7 R4 n) a3 j5 R8 l! Z$ X- ~. N) d7 f1 e" K$ t$ `) X
函数模板使用示例:2 ^2 S9 s! ]. w, C, _
在以上那段代码的后面加上以下代码:
2 j1 Q+ ~( F' W8 G# [! D! g" o
. P0 F: s4 ]" E2 A, V) P. S8 m- x  D) H- S
; m# I& |1 r: `4 N
1 _! ~% Y, t- f7 L' [- w程序代码:
- v2 m+ }: U( `2 A& c( [: z" j
  Q( z% h& x9 `" Y4 a# H( O: A#include<strstream>5 R/ @* C- {6 P( M
#include<iostream>  @& A" O& l0 |* |7 v( @+ T5 {; T! o$ l
#include<string>0 W% A) |+ t+ u3 ~7 C
using namespace std;% i* o; U: s) i0 O
int main(void)
0 m' o: S' ]1 L- O8 t' `. \{
  Z' m; q& g- x7 Y+ |    string s1;: `& {; s( G3 M+ @7 J
    while(cin>>s1)8 R* k! i6 ~9 C* o9 D7 z& J
    {* ~4 s  s5 d- I- ^5 }  x4 n- r
        istrstream isin(s1.data());$ p9 W% g% y1 a
        double d;2 ?2 j: l& d+ k! j4 m% \" E
        if(fy_Exp::GetExpValue(isin, d))
- H4 k* D: B4 o        {( M& ~/ ~  H# Y
            cout<<d<<endl;( C# _/ I( b- l" @" P
        }  _: E8 o0 |( C5 f
        else: @% M& \  G5 C# E6 O! a  K
        {0 S. ^1 s# J+ }1 Q$ O# V
            cout<<"ERROR"<<endl;
# @6 O0 A1 W/ ?" s4 Y$ v7 w        }  `9 O% g& L: R6 l9 S
    }, W: y. @: z' _; p! j) ^0 h7 N
    return 0;
& Q) ?6 _+ Q0 m. p7 o; t& L% H}" G2 C; J- W0 _" X, \9 n( c
+ w  f; d* M+ Y

& P- k9 Y2 l- l2 o& Y7 U4 v* E然后编译执行就可以了(*^_^*)
/ r, @# q. @) J( v. D* Q* d其它:TC++上一定编译错误,不保证在VC6上也能通过编译0 t: \! E0 P0 F9 T
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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