返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
( }' c' I8 p$ U  q0 C2 b一个很方便的函数模板,可以并且只可以计算含括号的四则表达式3 x$ P( J6 f# |: o* j
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
1 ^9 i; s  @7 \  {- O参数解释:: j. t& W+ |% D. |7 f0 z/ g% b7 h- j
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
  }+ h- m3 S( j5 [) x6 o! a1 VnReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定! Q/ r/ T- _; `; a2 q9 L4 K% G
返回值:0 }& Q5 i! t( L/ h2 s/ J
返回非0表示计算成功,0表示计算失败有错误
4 i, A+ b4 l% }
) v7 D9 w/ N# \$ Z7 q1 [
& I5 F2 _# H" \& m9 q
0 I( a4 b- c2 G" H: X程序代码: 7 ?$ X! }* j. m
+ ]8 b) Z% p) w' |
namespace fy_Exp{# o0 [0 A9 ^0 w  a
namespace {template <class _T>
1 v: p$ |2 `  s0 R. y: e1 D3 R! |* ?inline _T GetExpValue(_T t[], char& csym){
. {) n# `  h; X) \  J' A    char c=csym; csym=0;
* ^' E: y, l8 k% M1 m5 t6 w& T; ?/ Z    switch(c){
" E7 h8 L& W4 d  u+ U    case '+':return t[0] += t[1];
, |! e( u6 ^* o5 h- J' y    case '-':return t[0] -= t[1];  m6 R5 `" C- O
    case '*':return t[0] *= t[1];, I5 H& V6 d) }. n0 P1 V; w0 e4 w
    default: return t[0] /= t[1];//case '/':
8 H# s1 |9 c, i% l    }
2 c: d$ ]4 X9 |+ U7 u}}
7 Y6 u# n7 W% |+ x4 ]template <class _T, class _Tstream>
8 \7 G( M  W! e: `. z1 p' t/* _Tstream: inputstream, _T: get return value6 l0 ~! J1 |' f; H) a5 t" l
* Return nonzero if get value successfully */
. q% j0 `+ r7 t' G. s" Dint GetExpValue(_Tstream& istrin, _T& nReturn){
: O8 X4 x! A4 v' r  ]& N- I# Z0 v    _T t[3] = {0}; //雨中飞燕之作
) @( C) F4 l3 K4 V/ f2 f( Y# R2 |    char csym[3] = "++";
+ U$ H% y3 d0 m' m. i    int nLevel = 1, nERR = 0;/ M5 c) }' C' }6 x
    if(!(istrin>>t[1]))istrin.clear();3 s* @" ?9 _4 e) y' J( D0 f, a$ ^
    for(;;){
* V5 a% |0 Q: W& D. D  ~3 d& w        if(istrin>>csym[2]){6 l) e( W! z$ v/ b" |
            switch(csym[2]){* Y% r) I* e8 c* F5 n
            case '(':2 j- W" h& u# b& h, H
                if(!csym[1]){nLevel=0x100; nERR=1;}else7 z$ S: n( F# `: y/ w+ c, K
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
1 i1 [" n% P$ q8 Z+ _                else{nLevel=0x100; nERR=1;}
5 G' h! y+ y' a1 q) S                break;
- q/ I" n/ V) S$ x& ?; A- s            case ')':7 H2 z! s9 Q/ b
                {nLevel = 0x100;}break;$ G2 I& y) R6 F0 h
            case '+':case '-':case '*':case '/':5 L5 ?: A- d& C# n# L. K1 r
                {csym[nLevel++] = csym[2];}break;
- S. ~: ]) ]& w5 F+ N( l# O% h2 f            case ' ':case '\r':case '\n':case '\t':continue;; P, l7 o- z8 z: V: i+ C
            default:4 E; _  P2 s: Q. @) f3 g& i
                {nLevel=0x100; nERR=1;}8 o* K$ ]2 h7 b; q# U- t9 H
            }
- K% j7 \* ]# y0 h6 I' E            if(nLevel==0x100)break;1 ]' p8 {5 m  }+ [0 Z. b
            if(nLevel&0x10 || istrin>>t[2]){# r% b9 I: t1 L8 T9 o$ [
                nLevel &= 0xF;7 C6 ?; F, A* V, o+ b7 |; v# P) d
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
; l- X! a6 v5 K& @; K  [                if(csym[1]=='*'||csym[1]=='/'){& B, v- h2 ?, P: q% m" m
                    GetExpValue(t+1, csym[1]);5 `+ H4 [- s, x  ^$ F
                }
6 A  w1 b$ x+ C                else{
9 [; f1 B/ ~$ x. X: h3 r. H                    GetExpValue(t, csym[0]);
0 d8 L3 Q+ n/ I8 x. b/ y7 l0 w                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
6 t3 y* [/ E+ l" P                }' O. i" j1 T3 L! M8 R( _  |
                nLevel = 1;
; \! f% G) E9 d6 O0 G            }% }2 ~0 s7 c# D  T3 z
            else istrin.clear();
6 G% d( j0 O+ S, u7 }1 Q0 |        }
8 c+ ]# c- X1 L: V        else{nERR = -1; break;}
6 V  f& Z5 ^9 S! P1 [2 F    }& B. r- U( N3 z( k7 |) n
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);3 K1 x0 Z! w$ z! ^5 T+ S: N+ q
    else nReturn=GetExpValue(t, csym[0]);
/ t; S4 L, V5 ]1 w0 l( X    return nERR==-1?1:0;9 X2 b! I4 t9 U$ M: w3 o, m
}}& v7 N' Z5 W% [! ~- \; Y" M: }7 _
, l0 V0 U: v: F) o5 _' D. f

- n) Y" @# h) p: s: _( n6 F' f
2 D- `# `2 y5 R3 a5 Q" Z! K% v函数模板使用示例:+ j4 R. Y# _7 N& }  M5 Z9 `
在以上那段代码的后面加上以下代码:
" t/ e( W; a" F5 P. U4 [
1 i# n: Q! z7 V+ F$ |( \
: N1 w( B  V5 ~: R9 I+ Y. M5 [, j# j: ]" o4 v
程序代码:
) v: z4 w! H1 k5 }0 c4 F
: [7 g  ~; `6 g, G6 \- B5 W) B#include<strstream>
7 Y- c5 j) u1 ^0 }#include<iostream>: V3 f/ V6 T8 h2 k
#include<string>+ Z4 B6 {0 Y/ B, C
using namespace std;
7 P% O( {# j# ~, g% wint main(void)
% `! ?& h2 y) ^9 i6 A3 _{- l' O& e& |/ M3 F" T1 j) ]
    string s1;
7 b1 K  W8 \. C. S6 n    while(cin>>s1)
/ c) `2 |8 }( C: c* [( X* o& I    {
) K3 {2 }% R3 i7 x& \        istrstream isin(s1.data());
+ d- r  N% B: T- Z1 @* ~        double d;
1 y  e/ Z7 R, L- @1 X8 N4 N) A) t        if(fy_Exp::GetExpValue(isin, d))
: M/ Y0 z" ?( k6 \1 n# w3 A" A/ `: R        {
/ I0 W; z) ]8 e1 Q; {( A            cout<<d<<endl;% V3 r, I3 b/ Y% ?$ Y+ j; z
        }
, x( `; x. B( _5 R& L( u( t: Z        else' k/ r/ l8 F# B0 s
        {% ?6 q, [1 \5 q
            cout<<"ERROR"<<endl;  _0 v4 w- F8 r. k8 Z9 ~
        }
8 b; K4 M* ?1 U3 |* K    }
% q- M' `8 c2 w2 {* K    return 0;
2 X! \( E1 u6 G& C) |. e  q8 z}
2 ]( E/ T& F; H. b) q) t4 Z  \8 m0 M; O% X

+ C- C- X/ h: B' M然后编译执行就可以了(*^_^*)
8 h; G* H: f2 p其它:TC++上一定编译错误,不保证在VC6上也能通过编译
  c7 D: z; n$ t      建议使用VC7或VC更高版本,或者使用GNU C++编译

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