返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,% @  r. ~# ~: x1 O& B. L
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
. P4 C$ o/ f4 n' S只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)3 B6 M8 t  G& e, ]" e" t
参数解释:. t3 S" L1 m3 G" ^
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
2 t7 @9 E5 J- Y, S* \nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
, ~, s: H: f8 D1 Y  q, T0 p返回值:8 z- S+ t, S' n, L' ^4 R
返回非0表示计算成功,0表示计算失败有错误& m! T/ x% y+ u
, E/ e" M. N0 V& o$ k# Z* X
* o' Q. b' }) Z1 |! M# P
1 X, q+ Q: U9 U* |- f3 j& Q
程序代码: 5 B- Y! A7 ]  g. o
6 U' G8 O+ u1 Z2 v: A; V! @
namespace fy_Exp{% a, ^, p5 f9 K. v8 b
namespace {template <class _T>
; E5 ]$ }6 \/ g" q' \0 [inline _T GetExpValue(_T t[], char& csym){
/ q, Q0 z* U# f6 T. i4 ?    char c=csym; csym=0;% J7 ]" ^# ]; H
    switch(c){
- D# J# q5 B8 h  i% M  v9 C    case '+':return t[0] += t[1];1 }$ d: {2 w+ i: Z& p. R, @
    case '-':return t[0] -= t[1];9 d& J+ `* E% S
    case '*':return t[0] *= t[1];
) d8 E6 g. C' Q% [    default: return t[0] /= t[1];//case '/':
" j# s: M+ N( Q+ g, N    }# |" C: Y7 R+ n) j% s. t% o& ~1 F
}}7 G- R2 @3 H4 y: r* A9 z1 H
template <class _T, class _Tstream>0 J% s# ]9 b# D0 s* x9 h5 r
/* _Tstream: inputstream, _T: get return value
. E4 w: d" d: u2 m2 W0 C! u! j+ V* Return nonzero if get value successfully */
; Z6 |1 m3 k" Y7 G( zint GetExpValue(_Tstream& istrin, _T& nReturn){
+ q! Q$ y# @$ ?1 X    _T t[3] = {0}; //雨中飞燕之作
: }0 F, w; p% a. j$ }! k0 ?    char csym[3] = "++";, ]& u1 I1 l+ N" a+ O8 @$ S$ ]
    int nLevel = 1, nERR = 0;
" e. X, L3 G0 F8 e    if(!(istrin>>t[1]))istrin.clear();1 O  k# H8 ^7 R" t( Q8 c- `! Z! }2 f
    for(;;){% A. P6 y* L% f% X8 G/ L
        if(istrin>>csym[2]){. R8 R6 P+ i- q9 \& ~
            switch(csym[2]){
- {  o+ u4 N$ y; l1 b            case '(':! s# L8 W  s, i
                if(!csym[1]){nLevel=0x100; nERR=1;}else
/ y4 J! K' ?- Y& H                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;/ C- @. ~7 `+ b
                else{nLevel=0x100; nERR=1;}
9 I7 ~% m4 \4 W1 M* Q* ~                break;
( k6 E& M9 t. x, {4 ?5 V) x; Q* O- b            case ')':1 Q* _  W* j* q$ _* r" \& \( E# t
                {nLevel = 0x100;}break;0 \' g5 n/ O! n2 A$ a8 c* I
            case '+':case '-':case '*':case '/':9 k. W6 y$ k/ H8 w! t
                {csym[nLevel++] = csym[2];}break;0 k7 F1 p0 f6 q, d0 z' d7 H
            case ' ':case '\r':case '\n':case '\t':continue;5 g0 R7 m3 w3 ^0 ?8 B
            default:
7 h7 G# Z) F' y* m+ M+ N4 ]2 T                {nLevel=0x100; nERR=1;}
' C6 A% D. n! W( `6 s+ R  q            }
' W7 E8 J& z! L4 M& @( j; o            if(nLevel==0x100)break;
6 ?) F% ?# a+ E& q8 f  r9 [            if(nLevel&0x10 || istrin>>t[2]){; ]* Z+ T% j0 V
                nLevel &= 0xF;
& q+ e( |0 P/ j: g" ?                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
+ P" S4 w) `- M3 s# {                if(csym[1]=='*'||csym[1]=='/'){
8 K9 X* `/ v  d$ b                    GetExpValue(t+1, csym[1]);" k" }4 J, t7 D
                }
  ^, y; A  ^; A- [9 D; m/ B$ \                else{
6 h1 w/ ]7 O* w4 P                    GetExpValue(t, csym[0]);9 E* c! H) g6 ~6 P$ M- |# O
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
8 x3 S2 b  r3 l& ?: O2 i& x6 n2 R4 v                }
2 b( D2 n/ ~7 b3 R* i                nLevel = 1;+ j2 e& _* B4 Y& @, X
            }! m9 G: o! s7 v) }6 G
            else istrin.clear();
% Q: p: ~/ `0 @! e' ?        }
7 r2 F0 P3 e2 M9 x: S        else{nERR = -1; break;}
- P  p+ L& Z+ E6 E5 X; K4 e) i7 g    }  }& l6 D2 [/ O# J; C1 j8 Q
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
7 G% k8 T0 B# W  b" y. a    else nReturn=GetExpValue(t, csym[0]);
* r3 S- K  Q) X+ `4 H1 C    return nERR==-1?1:0;
$ d# X# A7 w0 I+ |4 d" r, c# a}}
! ~7 H+ B( m( ~  V# f/ r
- F6 W% p: V/ E5 W# C. N7 V! W4 ^0 U% P) u' ~. p; q! @9 {- x2 C

1 e3 ^4 \& u6 e6 l函数模板使用示例:; @2 Z0 E8 Q5 }
在以上那段代码的后面加上以下代码:
( X6 x! A9 u: z5 r0 V
" S  X% ]; {2 t5 e* S6 y! x ( I# S& b( A4 U0 f% m

; F0 V8 N, C' X6 _' n; v2 r程序代码:
6 F* a" |; C1 _3 u1 c9 g' g% q2 Y  S9 p, t  u! X
#include<strstream># [) m* S, d- }" }, U
#include<iostream>
- @$ H0 r3 l) {4 E+ N! I* [" c& q#include<string>
# F, @/ u8 y2 R/ g. m& T& v# ?6 s" N# eusing namespace std;
  ?, r* C  ^8 O: h7 q% `$ {* Rint main(void)
) L/ q2 k# A4 n" m' ?* X{- T. g: l# H- j1 ?" v' a
    string s1;+ @6 \1 s8 j6 F& s
    while(cin>>s1)
; u; t) Y6 ^" e8 ]; n7 t) k, t    {
$ ~* D; ]! o1 `7 r  a4 u6 G        istrstream isin(s1.data());5 k" d5 ~% |. r
        double d;
$ ]+ @) V) u9 l1 `9 y; R        if(fy_Exp::GetExpValue(isin, d))2 E# a2 B; Z: ~% y) y# R& H# u
        {1 l4 @  `: C3 D  |/ l5 g2 l
            cout<<d<<endl;7 s* T9 T7 b6 x0 }5 s& z
        }; h: M1 ^. a- p
        else$ U3 I% p$ Z0 |- k" p
        {4 _0 L0 z6 @8 p" }# n7 a6 r6 J. P
            cout<<"ERROR"<<endl;
% a8 {& A! k3 w9 D' c$ S" J        }
% @! Z) U) G; f" H0 A    }: Z; j0 o. m0 Q1 N; Y9 t: P# Z7 f
    return 0;, h0 f; k9 a1 l3 _$ N9 m" r' L) ]
}
' `  b  A# D5 ]  a: \2 d
1 @9 o( H9 n% S% ^
$ N* g! a7 x. U2 d6 u# }! h然后编译执行就可以了(*^_^*)+ h3 n( u; U2 ]. i; q: h
其它:TC++上一定编译错误,不保证在VC6上也能通过编译
+ e3 G# u4 A9 L6 ]* K8 z      建议使用VC7或VC更高版本,或者使用GNU C++编译

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