返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
( ?/ e  m' K2 k) I) e一个很方便的函数模板,可以并且只可以计算含括号的四则表达式5 ?6 H, @' M3 t8 }: u0 q
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)+ f: J, t( K7 a9 j
参数解释:
3 k) H! C/ ]0 U0 q0 o! Jistrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流+ G7 k  B+ w& ?$ o7 u2 X- S& u& v7 K
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
& S! g7 f& l/ L4 B% E返回值:
- c6 \, b7 o" K- ?: A9 `; O返回非0表示计算成功,0表示计算失败有错误& v1 M# s% L! z- |; _

, f+ Z6 A. T3 ] , K3 R. |$ R' e
3 O, e2 U+ l6 Z7 z+ _! G: p
程序代码:
) O7 ], E9 \, }4 D9 G" I- E' S! Q3 e9 I4 {% n$ K! q+ A+ h
namespace fy_Exp{# N/ x6 x* q/ t3 |0 u0 x- u, a
namespace {template <class _T>( X7 G7 o( ~* j
inline _T GetExpValue(_T t[], char& csym){
- p; ~9 `0 t" w" |# L    char c=csym; csym=0;
0 d4 ]  z5 X% G6 ^2 W+ a2 G) H( Z    switch(c){
: A5 ^; Y# v/ }+ ]9 K/ @; ?- T' F7 q    case '+':return t[0] += t[1];
# i$ z9 F( E% e- |- a# a8 F  \    case '-':return t[0] -= t[1];
8 [- M0 D+ t. y* Q    case '*':return t[0] *= t[1];
; `2 C9 o9 n2 ?1 l/ Z: v8 a    default: return t[0] /= t[1];//case '/':6 x& X% S6 P) c/ F
    }& j$ _8 N4 a$ V" m
}}
5 l3 T2 ]; \. `- J4 `) Etemplate <class _T, class _Tstream>) `; B0 z1 y; s
/* _Tstream: inputstream, _T: get return value
, e3 ]& L" J, K* Return nonzero if get value successfully */
0 I+ u) \! W  Sint GetExpValue(_Tstream& istrin, _T& nReturn){2 p$ ^' g4 I! P  c) C0 w* I2 Y. [
    _T t[3] = {0}; //雨中飞燕之作
1 b# l% a$ r! u# d) Z    char csym[3] = "++";  K  b( J2 k  [
    int nLevel = 1, nERR = 0;( ?9 P/ O; f' r5 b
    if(!(istrin>>t[1]))istrin.clear();
& d$ T& m# N7 ?- J: M2 Q) G    for(;;){
5 W( v- ?1 {. W, F) t        if(istrin>>csym[2]){
/ X- e3 ^! y: H6 e4 `3 S' k            switch(csym[2]){
& n: Z* N; |* H( f            case '(':
; M  ]0 i; |4 ^" K4 z; L0 K8 G                if(!csym[1]){nLevel=0x100; nERR=1;}else. ^3 H" c$ Z# A/ ~: `
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
3 w6 s* b9 o! k                else{nLevel=0x100; nERR=1;}+ X4 a0 j& Z" t9 E& h. e+ |6 A( j
                break;
+ ?: _& {$ w+ T8 `5 P            case ')':& x. Y2 t/ m; J) E9 Y7 x
                {nLevel = 0x100;}break;
) t3 U/ M" G+ q- N" c            case '+':case '-':case '*':case '/':0 E" ^- ^) J" p
                {csym[nLevel++] = csym[2];}break;- u( G. j' a' F& e* m* N! \, M2 k
            case ' ':case '\r':case '\n':case '\t':continue;7 g; N8 H- E; y: y/ G) V! x6 J
            default:
$ t4 R3 w) c1 r/ Z1 R; G1 i                {nLevel=0x100; nERR=1;}5 W  _& N3 D+ n3 L& J4 Y) V- Z, H" U
            }2 G3 b& e- _9 N, h# M% b
            if(nLevel==0x100)break;
& f" a* p/ |1 h            if(nLevel&0x10 || istrin>>t[2]){
5 j7 g, s8 c/ E3 |' M8 {                nLevel &= 0xF;
' v# c  |0 a4 n0 u: o                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
4 O1 M1 x6 G; @# Q$ k+ }' J( e                if(csym[1]=='*'||csym[1]=='/'){
( Z  `; L" ^- ^# R3 F' F! G                    GetExpValue(t+1, csym[1]);
. Q1 H; m* O& Q4 n$ ?  ?                }
) W: }& M' M5 |" ~1 [+ u                else{% Q) @. n+ w. R) k- e; m
                    GetExpValue(t, csym[0]);
; p& I: m+ Z0 A8 d                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;- U2 y; L" i4 B3 y; ]; w" i
                }
7 H( G6 Z2 [$ D                nLevel = 1;! F. u# }4 t0 S$ Z4 G' t
            }) {) |1 e, G# N4 Z
            else istrin.clear();
& p9 T$ u/ p5 ]& ]: y        }
: Z& O" y  B) d5 Y, w5 N! r) G6 B9 c        else{nERR = -1; break;}
$ L, @4 {3 i- i* }5 F    }$ E2 \# s8 i# U) @2 E! l- k
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
/ b6 C6 D3 y" W) Z! v    else nReturn=GetExpValue(t, csym[0]);
: `" Q1 F1 V4 @4 s. Y3 [    return nERR==-1?1:0;5 a# G2 `6 {% r7 k" w, g; Y! Z2 @
}}# Z$ Z! p; C: [7 Y; Y

: a2 ?2 R! I" h+ i& o# e6 B& V- w$ a# X2 Y' S- E$ J1 V" {5 l
% @' W2 u* O0 ]2 T: \+ |0 D
函数模板使用示例:
# s1 k6 R8 y- K1 l' ]& U+ _在以上那段代码的后面加上以下代码:1 }; M7 q$ ^. K" g' t5 h5 K

0 e3 E! g6 s3 f6 S- @+ e! H. w/ u
: n4 I. b. {9 u$ b( W2 A  t- |" L* M& w# o$ T- h6 r
程序代码:
5 _2 |% B/ X! q: L+ W
4 [1 k5 f/ v8 N, w4 k#include<strstream>  g/ A) P4 v1 s% }6 p! j. \
#include<iostream>
7 Q" M& P5 O  M#include<string>' O/ I, z( _" |) c. g# X* o  I
using namespace std;
9 [- d% Y/ Z& B4 {& [9 sint main(void)
+ s7 p: A+ W3 @3 _9 O5 i6 ~; V{7 Z( g5 P8 P" y
    string s1;
7 m* D& r9 X/ [; {  C' ]    while(cin>>s1)* ~" n( t; S8 ]. x' V
    {
$ J' x, S# Y% `# n/ M. O        istrstream isin(s1.data());
4 Q/ Q0 u7 D# Q, }- K% ~- A- R        double d;' p1 w- ~$ t) B
        if(fy_Exp::GetExpValue(isin, d))6 I/ K2 P' i/ W0 f( U
        {
" k9 {0 B0 |" Q. A0 y. Y            cout<<d<<endl;2 e' m- G6 C: e6 r2 t, e$ f
        }
4 X" ~0 m- D$ t1 a        else
* \* M4 f4 V) o$ ]( c8 F  B9 V        {$ S" B, P7 H& e: |
            cout<<"ERROR"<<endl;
, g" U1 W: C" R9 u, `4 ?' X: ]! i8 q        }
6 I/ T( I% [- s7 N& p, o4 V    }
  E8 s. N  S' c5 g- U+ \+ D    return 0;$ L$ y. `! z# N3 E! a
}
0 u' w6 s4 o8 w
# O( W1 t$ x* X: u( @# X. `( O6 m' G% ?0 s5 U. }
然后编译执行就可以了(*^_^*)
; ~2 v/ X, e$ K3 e) h+ B其它:TC++上一定编译错误,不保证在VC6上也能通过编译' c8 H0 s; q7 B2 p$ s$ d% p! Z
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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