返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
* L% p- M" P: q3 A8 Q# y一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
) H7 m2 h  ?" V" r6 y/ k& f6 n只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)* \% S: r- i" l  L3 y/ c
参数解释:- n# f) C+ J' a$ i
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流: w: ?# \+ d, S( }3 d! K
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定" E! |2 C# @' |) ^- x! b) ~$ [
返回值:
$ v  W$ p$ T: @5 G+ o4 g/ p" R返回非0表示计算成功,0表示计算失败有错误
& g, Z0 q0 ~# N; {- g
% \5 i0 ]8 c; d. {3 a! D ; N2 Y" P- S+ P3 h! A3 K* |: n9 _
# ]# y- N3 h" y; g$ j( p( f" |! z
程序代码: 8 g! U( Z* r: W, }0 N

6 X1 n) p; V. Wnamespace fy_Exp{: g) [+ d9 ]* Z- Z& G5 A2 R
namespace {template <class _T>. y  f8 @' i2 ^, V! c
inline _T GetExpValue(_T t[], char& csym){/ X& l* I* w- {$ \2 L
    char c=csym; csym=0;
, N3 `  p& S( K3 \4 e    switch(c){5 h! e4 q8 v5 b* W/ q6 L# i
    case '+':return t[0] += t[1];
3 ~6 O9 t7 {" a- K$ W, y# U    case '-':return t[0] -= t[1];/ i2 t5 e: Z0 e2 y/ h
    case '*':return t[0] *= t[1];5 G# c# _" ]$ _7 s8 b3 A
    default: return t[0] /= t[1];//case '/':
- d0 ~6 [/ p8 t! |4 A" f    }
' t0 S/ y% R- h4 C}}
7 X9 A/ s/ p0 L$ B- p4 v/ ytemplate <class _T, class _Tstream>
* U2 w' v$ d) e. ?! T, }/* _Tstream: inputstream, _T: get return value4 ]* ]7 P  N' V' Y* \# A' q  T/ e
* Return nonzero if get value successfully */, O# t* O$ E4 J: G, r; ^7 @
int GetExpValue(_Tstream& istrin, _T& nReturn){
6 K/ T7 G* R; P1 a0 M$ f0 r    _T t[3] = {0}; //雨中飞燕之作+ o# o( f4 J" U$ b6 E& `  T+ z
    char csym[3] = "++";! w+ O  j) t  p! L6 Z
    int nLevel = 1, nERR = 0;+ |7 I- @- e8 k  s
    if(!(istrin>>t[1]))istrin.clear();; r- Q/ F+ O1 u- I# d3 F( p7 O
    for(;;){
0 C% N) K; ~. Q* [6 A$ t        if(istrin>>csym[2]){- T/ A: O3 I8 h
            switch(csym[2]){' h! w2 N9 S, @& w! D
            case '(':
0 K( d. U0 w8 ?% ^+ W                if(!csym[1]){nLevel=0x100; nERR=1;}else7 N& \1 N& Z1 Q  g
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
6 ?6 n1 v6 s$ K                else{nLevel=0x100; nERR=1;}4 u" ~9 Y6 D2 I' v. F/ Y  X* ]
                break;
0 L; V) I6 k4 W, J( K  B4 Q            case ')':6 Y5 Z- `/ M7 z9 _" u
                {nLevel = 0x100;}break;6 P7 [" q5 }$ J: q, s: w  o. Y# b1 y
            case '+':case '-':case '*':case '/':! s. Y' \( h- A4 W9 j! p( v& I
                {csym[nLevel++] = csym[2];}break;: p. V/ i" a% Y, v: `
            case ' ':case '\r':case '\n':case '\t':continue;- X3 m1 P) U8 K+ U
            default:
8 p4 W, |( y) U# R" \6 K                {nLevel=0x100; nERR=1;}$ E& ~+ G$ w0 R- ~
            }
/ Z( y4 N: [' M$ f" _' }            if(nLevel==0x100)break;* L2 F& T/ W  Z, U' y' j
            if(nLevel&0x10 || istrin>>t[2]){
0 S1 b% R& u6 f' P                nLevel &= 0xF;1 l3 W' P0 a$ R% p
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}+ I" x( `; t+ n; A0 h
                if(csym[1]=='*'||csym[1]=='/'){
2 i. a: f6 B( V! _$ \; X                    GetExpValue(t+1, csym[1]);
# R5 Q* {6 b( h: M. ^" R( N! x0 U                }
. E$ P$ Y, D: y                else{3 V$ E  f! Y2 _5 Z7 \, `3 y; e
                    GetExpValue(t, csym[0]);( E) D* ]; Q3 R5 U4 c5 `& C7 c. w
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
  v3 k+ y2 g: ^; P+ a/ ^2 A: h                }) F/ ?" G, v$ L+ K1 ?' n9 h
                nLevel = 1;
- Q1 y; g% Z' \, e( A            }
% ^. z8 E9 Z8 B# f            else istrin.clear();
: f3 A# B" }3 y' S        }
5 x5 v  D1 m1 Y        else{nERR = -1; break;}9 f& b& w7 B) _
    }
3 R$ {1 j6 R, C+ p    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);4 A0 r! Z; R/ u
    else nReturn=GetExpValue(t, csym[0]);$ A' ?$ B2 h: P( e! x6 O2 E- k
    return nERR==-1?1:0;+ C) n- x! a" T& }
}}
' v1 k# [% G/ k- d& X* }# x3 P0 E$ V* \7 n
5 D5 I! i; z" h7 d( I
* r) S3 {3 l# g, ]
函数模板使用示例:
4 N# E" ^0 s' z- x8 V7 P在以上那段代码的后面加上以下代码:, a' n- ?1 J) |- w8 M- q- i
) I- \) k4 W6 ]* B$ D1 y
3 c# e5 v& E  r( N# a9 r
* H2 a: ?/ z' m% M
程序代码:
6 Q1 T- |+ _  p" Y  W& L4 Y4 b, m. C) n9 v3 X" I  t+ m
#include<strstream>, x2 y8 b2 n  o8 U8 |/ \
#include<iostream>6 j4 E  D' X" C% t
#include<string>
- |$ A* ?$ `# `% e0 uusing namespace std;
; U9 H, g9 q5 N* K% ?int main(void). j7 S6 k. w1 V3 r# _
{7 T0 q6 F6 j, `" e
    string s1;4 b8 f, y5 F" S4 M. N
    while(cin>>s1)
  Q( X# W5 h: ?1 V) h) _    {
- |* L* t) q0 }) `6 n8 g) G        istrstream isin(s1.data());
1 k8 }% n- c" l        double d;' U. U0 G- {$ O" V) v. B
        if(fy_Exp::GetExpValue(isin, d))
6 v! J" k( R) B; ~, w5 b+ O        {. ?6 j8 o- T5 t! q
            cout<<d<<endl;) e& q% f, K) j
        }6 }% S! t; s' ^8 ~6 O* Z+ w+ F
        else1 y1 N" w" |, f+ C
        {
' c9 U* K1 i$ k! C3 k8 Z0 g            cout<<"ERROR"<<endl;+ ~: ^% E$ C8 @3 O& Z
        }
' ~' l3 t$ }* W    }2 h' N9 {7 c8 a& [  h. }; X2 r
    return 0;
: v3 c2 B# O( H}, A5 E7 x- y$ o+ t( F  j' s- J$ E
1 Q! m/ m6 q9 y- b' s. i9 g, e9 U

4 u4 X/ b, q" e* P然后编译执行就可以了(*^_^*)
  q, J: ]+ t" D' |+ B' n6 o其它:TC++上一定编译错误,不保证在VC6上也能通过编译  d. F/ e: W# J& x, o; r1 W; T
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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