返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
5 b; ?* z" Y2 J! t- ?6 k一个很方便的函数模板,可以并且只可以计算含括号的四则表达式; y$ {' U5 F& o. n/ r) Y, S
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)- H! D* s& W% |" d
参数解释:( r# F5 a0 w; I. y1 K( f4 t
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流; D) c8 y# m9 V7 b: \/ s% c
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定% [5 i0 y  d5 U  w* l$ x  V
返回值:
! x; b5 T! F+ z返回非0表示计算成功,0表示计算失败有错误0 u1 e0 X$ }! B& U) q$ j6 E

2 J, ?' B- K# |$ N 4 G* Y4 u! H$ s, Y0 h8 ~- f
& I& T# z- J- _% q" V2 C
程序代码: 3 k' j. J1 ?/ N% O! f

6 r+ W- ^3 ?) ~: jnamespace fy_Exp{. L3 ]$ l0 L' X5 B1 N
namespace {template <class _T># O0 @, Y' K. y5 R# o
inline _T GetExpValue(_T t[], char& csym){$ f- c  t1 `- C& A( |
    char c=csym; csym=0;
6 |7 r( ^+ W/ H    switch(c){
% r1 x+ ]( E# V/ W7 Q    case '+':return t[0] += t[1];
. P  T2 ~/ Y6 _5 ^+ F: F' @    case '-':return t[0] -= t[1];0 r0 e9 f  s# s1 a) ?
    case '*':return t[0] *= t[1];
* I2 D- A8 C5 P9 u. b8 T    default: return t[0] /= t[1];//case '/':
9 G  k  k# S# n$ k. l$ ]    }
5 v: Z0 u# U2 h! }2 _}}* U) ]* ]) H8 L8 T1 Y/ @3 {. e
template <class _T, class _Tstream>. H- i; ?  W, x) {* l' `% L3 Z
/* _Tstream: inputstream, _T: get return value' T7 }' ?5 S' a/ ^) m; G
* Return nonzero if get value successfully */
2 W: T& n9 x' C6 Lint GetExpValue(_Tstream& istrin, _T& nReturn){4 e# R( C" Z' z* B  q. p* }
    _T t[3] = {0}; //雨中飞燕之作
+ `/ m) S/ X/ x. m% P' r4 b7 u2 {! B    char csym[3] = "++";/ p  y( W1 `2 `) x3 e  @; C
    int nLevel = 1, nERR = 0;
4 o" E, a/ \% w8 ?1 {* p/ u  A. V    if(!(istrin>>t[1]))istrin.clear();
/ [* o7 E$ l' ~    for(;;){
/ {* }0 `9 S! u6 Y6 o        if(istrin>>csym[2]){
( x" H; w* s% [  w            switch(csym[2]){
2 r9 ~2 h* T0 d: p9 O, N            case '(':0 ]% K/ Q, E6 G$ z) l( F
                if(!csym[1]){nLevel=0x100; nERR=1;}else# z) t6 b: A! l1 |9 C3 H3 v! W
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;8 T& Z- B7 C" q/ n
                else{nLevel=0x100; nERR=1;}
- |3 F' x8 r( i/ |9 o3 E                break;. W: r; x; X" u0 s/ d! q/ w
            case ')':
3 ]1 Z2 X6 _6 R; @1 ]6 D9 \4 A1 ]# L                {nLevel = 0x100;}break;4 M+ _) Z0 |+ O: [; B: c( W& s- `
            case '+':case '-':case '*':case '/':
# `0 J3 }  E% O, l3 i                {csym[nLevel++] = csym[2];}break;7 J* p5 q% |5 h' ]$ {* L* f
            case ' ':case '\r':case '\n':case '\t':continue;
* L& _, X0 T5 W$ N5 j6 L            default:
+ A; N4 e; e# C" {7 K                {nLevel=0x100; nERR=1;}* X' v! R- J9 l& |  y2 i
            }2 h7 P6 F& {6 T( ~5 @5 M) n
            if(nLevel==0x100)break;2 Z5 v+ X. C: {8 D- X
            if(nLevel&0x10 || istrin>>t[2]){( V# V6 |3 ]7 w) P
                nLevel &= 0xF;2 _( Q5 L3 |6 U0 s2 u
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
% l- ^7 ^. P' O% {; O  H                if(csym[1]=='*'||csym[1]=='/'){
* B3 ~0 E9 a- \. C4 |/ P4 z* [                    GetExpValue(t+1, csym[1]);
& v9 N/ k, X  Q. I                }3 [5 Z6 G0 s  K: p/ q5 {
                else{
$ l/ ]( x: X- [0 i# S- s& ]$ d5 L" W                    GetExpValue(t, csym[0]);
8 }. e$ D* P5 S# K; i6 D, e                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
2 m$ l5 _! h* r5 [                }
% x$ v  B8 ~# f) d% T- L                nLevel = 1;
8 V) I5 K0 ?6 a2 N2 W            }
: `. U4 y+ q& @. W9 h            else istrin.clear();7 g8 r& `0 r$ u$ d  |, a( N9 O
        }6 V$ N2 m) p: J6 Y
        else{nERR = -1; break;}
+ G3 e; \3 ?4 T) w( ^5 `7 L7 {! R    }
" p9 n. e+ V! u    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
7 W' s, G* f6 v2 X" H; W/ E/ X  }    else nReturn=GetExpValue(t, csym[0]);( D, }# }8 O* y7 T7 c
    return nERR==-1?1:0;
" s9 ?5 o7 W3 A3 t$ [4 h}}
+ }" E, g' [4 p; ?0 T1 @- f
0 Z( ]+ t7 z8 F' R, b) R! f( s% c- x, }, u# M2 E

+ x% ~4 f8 ^+ }3 d3 `函数模板使用示例:
' b0 y* Y0 z% O: F2 C在以上那段代码的后面加上以下代码:
7 D9 z" e$ d8 n2 Q: j/ l- M: b3 N
. g( Z- p# g3 X1 g4 w  X3 X+ H
( h7 s/ I# {) C9 r  d' i. _
- w  c2 t( M! E# p( e程序代码:
( q, S  H; J& N5 ?+ k* g' K; a2 s  I6 O
#include<strstream>
  I- D3 j5 j! q$ j, v#include<iostream>- M4 `3 [7 `$ ], \" c5 K2 i
#include<string>
6 h+ i/ x5 J7 s% Z8 B2 nusing namespace std;
! x: }" i4 |- b2 ]) W( Rint main(void)
9 Y5 A8 q* u0 u' x3 Z/ g{; O6 p. m# E5 O& }
    string s1;3 r" Z% e" Z0 y! q' V
    while(cin>>s1)
) }- {- \) v8 v5 [& x3 m5 t    {
) j; F4 C7 y- T/ H  q) [; _        istrstream isin(s1.data());0 {& V2 q; y2 K* l* U2 m
        double d;. h, V/ t3 n7 h
        if(fy_Exp::GetExpValue(isin, d))
, y5 T' \. P( w) \1 d7 R6 {        {+ G8 R8 |7 [( U# F- l7 I" L6 F
            cout<<d<<endl;$ }& G. y+ s; O  K) b
        }  a8 z! z9 Z3 M
        else3 H" ~( T/ y9 g7 L/ P
        {4 D. J2 y8 `* d$ H7 A
            cout<<"ERROR"<<endl;6 R- y( f+ c- f* V
        }4 }# }8 J, T' H& l2 E  O; \( F
    }
: E7 C" d, R. J7 c5 }    return 0;8 w' s& o* g$ [" V2 b: j! H5 i
}
. K5 E  m" ?& n) O0 S8 r. G! m7 B* L- g
6 Y) W- f. {* l2 B) T% r
然后编译执行就可以了(*^_^*)
$ G! r7 Z2 ~( m$ I) Q; ~8 K( ^其它:TC++上一定编译错误,不保证在VC6上也能通过编译5 D; R( j) E! B
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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