返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
; T4 P8 b6 [. x- m1 I$ R) b一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
" K' J8 ?1 v+ ?6 _% d$ e, G7 z. D* e只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
; Q3 y7 r7 U9 Y/ B% m1 S# v* T参数解释:0 i+ }3 G" h: V- m$ _6 W
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流) d% H) M9 d5 U) y* i$ I0 \$ h. x! W
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定, I4 J7 j) V0 z
返回值:
% P9 ~% q% e4 w1 u( t+ ]返回非0表示计算成功,0表示计算失败有错误
: `& ^' M& M$ b5 T
- m. M1 U% d- I2 [. ^5 }. J ) j* H- X* x" d$ z

( f- d5 Y+ n6 [( W程序代码:
) m& [. b4 y8 p* J! k& n$ k& M1 W5 x! |2 |, t) }  I
namespace fy_Exp{8 D2 V/ q: M0 C% T
namespace {template <class _T>7 \: o7 m  ]% o+ `0 n% t! M. }( v5 l
inline _T GetExpValue(_T t[], char& csym){
) w. _" }1 \8 b7 {    char c=csym; csym=0;: ^( B1 D7 n# p1 I% i" Q
    switch(c){
6 K6 @! ]5 J: ^  l    case '+':return t[0] += t[1];
& C0 u/ E' i7 u! D/ W/ y. s0 C    case '-':return t[0] -= t[1];
& u) M5 ~1 I! v# b' a: T& C4 A    case '*':return t[0] *= t[1];
! N* m" a- _. \; Y    default: return t[0] /= t[1];//case '/':: x$ d& d' }7 n
    }
% s0 d4 F  E9 C5 _0 O}}
7 p- i; |1 l& ]8 ~, k2 Dtemplate <class _T, class _Tstream>* _& I' O+ M7 \# l" m! ?1 ]
/* _Tstream: inputstream, _T: get return value5 w9 M' c/ l4 ]  h# L2 u0 B
* Return nonzero if get value successfully */
% d0 X$ N# B9 O. Q/ j/ q  aint GetExpValue(_Tstream& istrin, _T& nReturn){
8 b" ?9 ?7 ?! W4 p1 ]+ v# X    _T t[3] = {0}; //雨中飞燕之作
, ?, p# z& Q8 w" X( T    char csym[3] = "++";
7 u; x- ~  g1 ?/ f) G3 n. m    int nLevel = 1, nERR = 0;
6 `" _( Q4 n! A2 j1 e" ?    if(!(istrin>>t[1]))istrin.clear();0 j' \' l5 ^- @* f6 F+ k0 l
    for(;;){
; E* z+ I8 s. s7 s" G5 V; [0 X        if(istrin>>csym[2]){
2 n7 c, ?! p$ i% A            switch(csym[2]){6 _1 @! p: Q3 ?, R
            case '(':
" o8 J# [4 u+ P/ l+ k5 t. C                if(!csym[1]){nLevel=0x100; nERR=1;}else
, b2 O! X, m$ {8 l. z                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
. H0 w/ ?3 O" u  N* E* b: X, o                else{nLevel=0x100; nERR=1;}# r2 A% {) |: c) F9 C
                break;
. H1 h& G) @! ?2 M- G8 w            case ')':* y  x4 U. B9 t( V
                {nLevel = 0x100;}break;
4 Q0 Y# ~5 e/ W8 h+ W5 l            case '+':case '-':case '*':case '/':! U- X4 h) a& X; t! i, J3 C
                {csym[nLevel++] = csym[2];}break;7 P4 j  {( c) r% W! v
            case ' ':case '\r':case '\n':case '\t':continue;0 U7 E( \2 O9 I' Q# R4 K! r
            default:0 b# u0 K) P  r$ |9 F. N& U
                {nLevel=0x100; nERR=1;}" D3 J% ]) m- H: O6 o4 J
            }9 g( c  M2 P- K+ N8 V
            if(nLevel==0x100)break;
1 N$ H+ p  L% ^) z            if(nLevel&0x10 || istrin>>t[2]){
, I  A! J$ r  E0 J$ T. d3 z$ v- z) f                nLevel &= 0xF;# k# I; L4 Q2 E9 G9 f- h4 h/ b
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}' I+ n2 T+ p* c2 P0 X! N3 c; q
                if(csym[1]=='*'||csym[1]=='/'){5 U, I, j- O" U7 S* p0 n
                    GetExpValue(t+1, csym[1]);) J& N& F- j9 I) E% Q
                }) \8 P, D7 E! u( X; v6 z( N3 t
                else{- Q; ?4 N/ n) v; t# ]) J
                    GetExpValue(t, csym[0]);
3 A" ~3 ?; q  ^) K                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
+ t2 p% `/ {/ Q( K- s" f7 s                }
- @/ s1 F; W% y$ _* t! n" v' ?                nLevel = 1;. Z1 N0 Y/ z5 L8 F0 q) M1 i% l1 A
            }
  u( P: R1 p4 _  P            else istrin.clear();
$ C2 N% [* q  ^- n* c        }
+ M# o% \3 ~& W/ @        else{nERR = -1; break;}1 U7 s; s. G- T# u
    }2 C8 h; m) j- P/ x
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
$ |9 E' [  p6 p3 S- T/ C    else nReturn=GetExpValue(t, csym[0]);
% d* r; m6 t& b4 M/ Q& b- Q    return nERR==-1?1:0;  u7 d8 b# x$ j3 D7 g8 w! U
}}  }, y* r# H6 ?% N

" i4 w& V8 F7 A. J/ k
$ W8 M2 d- ]# Q# _+ ]1 x% x$ z( ~) R  m& P1 u& y
函数模板使用示例:
, I2 _6 T2 i5 L- S# Z在以上那段代码的后面加上以下代码:
, R, A/ N; s6 u# F1 b* X& H/ W& p; w4 h, K3 N

; M0 ~3 W# {) Y9 y. w7 W9 ^2 n* q  B) ]
程序代码: 2 J( U6 F; v! }! q

% V6 Q. k, F% [#include<strstream>
. w, m6 v% Z6 O- a  D! A, M! K#include<iostream>
6 I( Y3 M# j7 M' v9 L#include<string># I- W  z2 X1 s) p) h
using namespace std;1 Y0 U, z6 M3 O- N
int main(void)
8 R, p$ _4 @% \1 I$ ^$ ]{& Z" @/ B6 t" R: Y* {. v
    string s1;' \4 y. t' i3 v/ [1 L* U
    while(cin>>s1)4 z( P3 z/ ~. U
    {% T3 J1 t, x* N9 u' q
        istrstream isin(s1.data());* E! _+ y: p( v) K# n
        double d;, X6 y0 U- l( ]8 C5 d2 f& K- v: p
        if(fy_Exp::GetExpValue(isin, d))
$ `2 l3 C6 @* I# I1 c        {
, }$ d1 c7 A5 s! n; t: j            cout<<d<<endl;/ q+ k9 a9 O! a( B) P- o
        }
; e9 V. b, C& W% w        else: N' [- `- o% v, Q' b/ |! S1 e
        {# v0 S; _0 J9 ~, n8 s# N; Z
            cout<<"ERROR"<<endl;
8 V% B) F# l- ^& K6 X( j        }, _$ J& [! x4 @; ~# n
    }
# ~7 R! q- _& `2 c4 Q+ `) |# K6 ?    return 0;1 X7 A9 a* y5 a4 S
}- A  g) |- U! |0 x9 @
. x. E- \! f. H# I  ]
8 l1 z4 y- M+ _9 S$ K
然后编译执行就可以了(*^_^*)
# u- @& G3 ^0 ~% U+ h其它:TC++上一定编译错误,不保证在VC6上也能通过编译
2 Y, H  V) D3 w1 v      建议使用VC7或VC更高版本,或者使用GNU C++编译

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