返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
! N7 I; A' `% X. r& S一个很方便的函数模板,可以并且只可以计算含括号的四则表达式2 ^) }' E3 o, K+ k7 S7 U; y  [* \
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
, c: }. Q2 o( r参数解释:
3 \2 g8 ], F0 g, D/ h* fistrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流* O2 }2 U! |! \/ L7 \! j
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
( z, g0 p+ O- c1 z8 p( l3 V返回值:
& c9 l' Z$ X. j; Y  Q- _返回非0表示计算成功,0表示计算失败有错误
" b& s, j0 c  W4 w# x9 q. m  y' F/ p+ t* @. p$ w; `
+ w1 n; u+ G" {- s3 I# O7 j

5 z, o# K- \' A9 `# `. ?程序代码:
5 }. }; D$ G6 x  A' [. \/ ^+ B. T3 _+ q- V; i; V; d. }
namespace fy_Exp{5 e9 z+ K; o: g" y
namespace {template <class _T>( t- f" k" O% a8 Y* e4 X1 \, ~
inline _T GetExpValue(_T t[], char& csym){
9 G( \4 b3 e6 o' j* u    char c=csym; csym=0;
% q+ |; d$ u9 T6 E+ J4 w% M    switch(c){' _, V' R. i1 q( [9 f
    case '+':return t[0] += t[1];) s% a" c# l9 V& s- n
    case '-':return t[0] -= t[1];8 _$ I7 N4 ]- J5 ^' U
    case '*':return t[0] *= t[1];
/ o+ p( E& i6 T* ^6 v    default: return t[0] /= t[1];//case '/':5 {6 I' t+ |: C1 }% N' Z
    }6 ^" o- h, m. I: I
}}# c* S* ?% I, Q# m
template <class _T, class _Tstream>
+ u; ~% l4 A9 w3 i3 C, a0 N/* _Tstream: inputstream, _T: get return value  ?1 |* u3 n* B; s- L! _3 k
* Return nonzero if get value successfully */
6 Y; J! ^) v+ w0 e3 X: C" cint GetExpValue(_Tstream& istrin, _T& nReturn){  _, r! \' D9 }$ R8 d
    _T t[3] = {0}; //雨中飞燕之作7 @, r% @) @% y$ ^
    char csym[3] = "++";9 j( V! c& p: x+ S9 T$ H
    int nLevel = 1, nERR = 0;
7 ~, w. J' U2 y0 w    if(!(istrin>>t[1]))istrin.clear();
4 {2 G& B# l+ c: d  a' Q) R9 ^: n8 o9 i    for(;;){
* b2 [" }! k" m        if(istrin>>csym[2]){
  l3 Y5 N9 f9 {0 a            switch(csym[2]){
7 U: B. X% t$ R5 B            case '(':
: b# }7 c7 `1 L7 m) Q; T                if(!csym[1]){nLevel=0x100; nERR=1;}else: u9 j( o. G5 d4 k( i
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;: t3 |5 B/ c$ {1 Q1 W) ]1 t
                else{nLevel=0x100; nERR=1;}4 Y3 j* b( U3 b
                break;4 y1 e: `6 E+ U
            case ')':
% M) k" p0 e$ n6 s                {nLevel = 0x100;}break;
  L4 f( h" Z6 T$ {1 ]6 j            case '+':case '-':case '*':case '/':5 |$ Q9 r. h: p$ B& @' u# F
                {csym[nLevel++] = csym[2];}break;% b. U& i4 A- i9 z) y" J; e, m  F
            case ' ':case '\r':case '\n':case '\t':continue;# @7 H( h7 V+ g3 G& s
            default:
6 x% O% I4 b! Q7 H) a                {nLevel=0x100; nERR=1;}: t/ U& H9 {# \' f' U
            }
# T  g0 ~1 V: c4 Q            if(nLevel==0x100)break;" d+ X3 N; G. n& u+ G
            if(nLevel&0x10 || istrin>>t[2]){! O: i# N0 k) ]0 c7 O* q/ f4 W
                nLevel &= 0xF;
$ G* E- g: z7 C3 L  R+ Y5 b                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}  N/ |; y2 w, ~2 z
                if(csym[1]=='*'||csym[1]=='/'){
8 n8 f& u7 q5 D4 u! E- G" J2 Z                    GetExpValue(t+1, csym[1]);
! e) V! R. i- M8 B! ~# i                }; C5 N5 i! F$ Q7 k# }9 p4 h
                else{5 n" q  C5 s6 e' q* ]4 o' ]+ k
                    GetExpValue(t, csym[0]);
! E9 }0 z& d4 [: A8 I6 ~" D                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;' |4 P, E6 q. l7 n7 S4 [
                }
- N2 X/ l  t* ~$ k; ]- s5 ]  h                nLevel = 1;( ?, B; X* _9 y- k4 X! u. `2 K: g
            }
* I5 |/ w7 G& N7 X1 L& k" n            else istrin.clear();* F. x: M8 O  p! ], T
        }; `* p; h  b3 s$ d
        else{nERR = -1; break;}
3 i, A- L! \, N0 l    }
+ W) z, @! D1 Q& P, w9 Y    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
/ Y0 z7 C* w4 n# w% a    else nReturn=GetExpValue(t, csym[0]);
2 {* D4 m; P$ _, w. c    return nERR==-1?1:0;
9 Z' q, W- v7 Q8 b# [}}, r/ _" g# |5 Z/ ^# |8 [! C5 [2 f8 M8 \

7 q" A; s( w. |2 j& U* }( S' A7 |2 H& S5 k) L4 m0 _2 N  j9 Z9 l3 d

0 k' _5 V$ n* s) x: _函数模板使用示例:
, K# K& V1 T! h$ P8 R在以上那段代码的后面加上以下代码:7 M7 M8 M) i; d* z/ I

, |; T: S1 t: Q+ J1 x! b" i ) }! f0 l3 u9 M8 |+ v# `  n

1 C6 r  c* Q- |7 I* w程序代码: 4 g% K" B: {% y& T, N% T

0 o% N* `6 E  x# M' c#include<strstream>) d0 B* u+ i3 K% f6 K
#include<iostream>
+ e; H5 x  ~2 I- }$ Z  f: B#include<string>" k+ |3 s6 u7 |0 N
using namespace std;
" ^) O+ E( x+ Oint main(void)
4 U( }. X: [/ ^  r. X% h0 z* V{6 n2 [. a" U7 K
    string s1;% ?1 b5 ^' E( _+ y7 }/ W5 d
    while(cin>>s1)
1 l2 W$ V% v( e% |% `: o8 w+ h    {
1 b* Q& Q3 F4 E; ~5 P! n& w        istrstream isin(s1.data());
- X0 s2 U0 D8 }# a. X2 Y        double d;  |/ P, F4 o2 l
        if(fy_Exp::GetExpValue(isin, d))
  @3 H* e- D* y5 V        {
# F- o7 G: n  R( w. g& a- Q8 ]            cout<<d<<endl;/ W) H) J" ?% [9 }
        }* \3 S5 y" k8 |: B- k
        else
' k( v9 ?0 S3 f, A9 L4 _2 k8 }        {, @+ j6 M$ m6 ^# s; G# k' J
            cout<<"ERROR"<<endl;5 l5 {8 G7 h) u6 t& d# ~  [
        }: m" c" s# F/ l$ O, y
    }
) t* N* L& |2 V/ G! ?    return 0;
6 ]. {$ L) f( _}1 K* T; `& c: W3 k1 Q6 D
7 j" u# _: |) |  X9 R
( S! v9 f, b- G# N) \- z( Y
然后编译执行就可以了(*^_^*)5 \" l" @$ U) @3 s' v
其它:TC++上一定编译错误,不保证在VC6上也能通过编译- p0 S/ n1 a5 |# d3 u/ k* l
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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