返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
: c( @* [, C0 m9 v  d: O一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
0 j# T) K" H% I/ v& }& _. m& Y: U只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
9 L  `+ W6 U7 ~7 k4 h参数解释:
( l" ?/ e# h) l. ]8 Listrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
# z5 o, N! _+ }9 W. x5 O8 CnReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
" j" m# @/ o0 k, @返回值:" O7 B) B4 B+ F
返回非0表示计算成功,0表示计算失败有错误3 P0 O" Y& t" z( x7 ]" J2 b
# y* Z9 y* g/ J7 r

1 P3 N; L3 B. Z& E, B5 z
; T1 N+ G/ A3 ?+ e* [# X: ]6 o( O" F程序代码:
* O3 N6 U8 d3 G6 M
0 p1 _, ?9 u; K2 l. H" vnamespace fy_Exp{
4 P6 z, J* X/ K- m5 j; r, y; J0 K( @namespace {template <class _T>
* W" h! j, i5 h9 u. H' E' y" ginline _T GetExpValue(_T t[], char& csym){
, {7 g1 k6 T" N0 y    char c=csym; csym=0;+ ~: ?) z) u/ H% w4 t; X+ y
    switch(c){
  H4 W8 b& N% _$ ~    case '+':return t[0] += t[1];- S' U# f& i$ b' G1 u, r
    case '-':return t[0] -= t[1];
! C7 X+ O: T# g" G$ F3 S3 Y: ]    case '*':return t[0] *= t[1];. b6 r- p! C: E6 M" U* i/ ]
    default: return t[0] /= t[1];//case '/':9 Z) W  e3 Z* o' a( h
    }  W( A/ Y$ y: z9 R( p4 U' A2 A6 S
}}1 ~$ m6 r3 f! q( {' g
template <class _T, class _Tstream>
+ D7 ^# C2 y* Q/* _Tstream: inputstream, _T: get return value
: g$ y3 L" H/ t' ^$ I# N* Return nonzero if get value successfully */4 q- Y6 v2 @& ]5 @+ H3 j. \2 q
int GetExpValue(_Tstream& istrin, _T& nReturn){
: u) V" {" F* t8 @8 }1 [5 t) O4 e7 b    _T t[3] = {0}; //雨中飞燕之作
/ @7 Z' z2 b/ o& d6 f. }# G0 ~    char csym[3] = "++";- h# N, n1 B7 A
    int nLevel = 1, nERR = 0;
" t. Z' Z& H3 z" g- k    if(!(istrin>>t[1]))istrin.clear();# o5 B7 O0 d4 X  E9 l$ X
    for(;;){
! T% J: C& N# W5 j2 s' ]3 V- M        if(istrin>>csym[2]){
! W4 D) o1 m2 R% f. f+ [& y0 w            switch(csym[2]){1 B$ Z& b9 x# h; o- L  O
            case '(':/ z8 J5 y. f6 g$ }( W
                if(!csym[1]){nLevel=0x100; nERR=1;}else7 l" `: t2 L, c, R9 T( ]/ l
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
; u' }3 t' Z& V! X                else{nLevel=0x100; nERR=1;}0 W- M" y! v1 D( ?) o$ i; n8 p  e. X
                break;
+ n, Q4 y1 w: L& A            case ')':" r+ ^2 U7 Q% p
                {nLevel = 0x100;}break;
9 X4 w* P/ v( P( S- v            case '+':case '-':case '*':case '/':  N6 b2 A4 |+ o/ J1 E0 B
                {csym[nLevel++] = csym[2];}break;/ t. d1 g+ q, V. ]4 r$ C
            case ' ':case '\r':case '\n':case '\t':continue;
" }" I. Z" d* X            default:7 Z2 a% D$ i: I& s3 B, V, w
                {nLevel=0x100; nERR=1;}
6 Y) B6 A- y0 _* Z            }" l* R0 d9 i# G  O& W
            if(nLevel==0x100)break;2 r2 p: u; R5 j
            if(nLevel&0x10 || istrin>>t[2]){* w% k% W" m  L4 X/ t
                nLevel &= 0xF;9 y) h+ W# Z, p7 S5 N( B
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}1 A: N3 k% D3 h% B* V
                if(csym[1]=='*'||csym[1]=='/'){/ h1 o' K) y' Z; k5 |% A) l
                    GetExpValue(t+1, csym[1]);
+ Q% T& I9 k3 B% q. W' [                }2 i: p+ h: c& e+ ]. [! ^. l
                else{& M7 O. A2 r: r4 ^2 Y' ?" H
                    GetExpValue(t, csym[0]);
* B  K3 {5 {9 n4 s                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;. b' {5 \( ?' `# b4 g
                }
) i, a/ {* J- T: z                nLevel = 1;+ I1 C+ i" n# ]" _$ P6 |" y  W2 l
            }
2 j$ X# n4 Z2 F* {            else istrin.clear();, U' Q9 O# i, M0 Y
        }1 _$ n: ?5 E' {
        else{nERR = -1; break;}; Q6 ~2 M: [* V  N
    }
9 ?( r; J6 {9 ~4 w    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);- C+ m+ n, r2 x2 f% T
    else nReturn=GetExpValue(t, csym[0]);+ l6 R2 X8 @! I- L7 X7 R3 |
    return nERR==-1?1:0;
% A; z' f/ Q1 `' ~8 n# q6 v}}6 X8 s% I2 Q$ p- Y

& H4 C6 y/ i* g3 z5 O- i$ Q! k. k  Q
" ^8 r! G9 D* t  m
函数模板使用示例:8 G; a# r2 e7 A8 N1 ^, ?
在以上那段代码的后面加上以下代码:' [& Z" U; g, c* l9 U- }

: `4 k4 Q- J2 ]8 y, K) c9 a8 k 7 O1 K- t, x3 A' V
, \. |; a- }" L/ Q% ]" o& k
程序代码: 1 `- X: U1 c, l) h3 }5 j; i

. Y6 z! S$ @- n- K#include<strstream>
  q* y) J6 f, h#include<iostream>; v" m9 g3 E) a8 P5 x1 |& E) S( A, K
#include<string>( ~1 e, Z- R' X" b: f4 F. C5 o- u1 Q# P
using namespace std;
  f+ d, O8 A3 B) X2 Xint main(void)
/ f9 V# U7 J$ T3 D{6 F( a- v, u3 B: L4 \
    string s1;1 P6 x  `: Q3 v7 d* ^6 S( F! b# S
    while(cin>>s1)2 `& f3 t% _: A6 Q4 j6 }/ l0 j
    {
/ I3 {& s4 ^$ \9 c7 r, k/ b) |        istrstream isin(s1.data());
4 @* ]+ J  C& b" w- L8 G        double d;  E% c3 K/ J. p  o6 h) f
        if(fy_Exp::GetExpValue(isin, d))) [+ u3 C4 ]3 K9 K$ W8 |/ b
        {6 Y3 ~# U% _4 M2 |6 j* S
            cout<<d<<endl;8 O; U0 P4 w/ I  P  ?, U
        }9 `8 Q' w' x$ k  Q7 J, h
        else% U4 d7 I. @3 h& t& |
        {
# t# e! S- G( w: P; N1 b& R            cout<<"ERROR"<<endl;& e9 J6 j2 n; E5 d2 ]- u7 F; K
        }
( C9 }5 {/ G$ f0 a8 Z! y+ i- }7 s    }
) V! T% {7 U* [( E    return 0;
! B; N  r6 b# E( O6 z9 ~. `+ f* \8 y}
( c( Y4 z  q2 {7 Z1 ?5 ?
2 |/ Z, j* _7 D) A$ S+ k& Z' i9 z* y" W' x+ D) C! a' d
然后编译执行就可以了(*^_^*)8 x6 r$ G8 y$ R' q) i9 p  F2 q
其它:TC++上一定编译错误,不保证在VC6上也能通过编译
9 a9 G6 o0 I' w      建议使用VC7或VC更高版本,或者使用GNU C++编译

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