返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,! f  h( s8 T' ?' S: G+ S3 G% b5 B
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
$ U( W) Y1 `0 F' T只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)6 \/ U& S8 b3 a2 t$ L& f" }/ \
参数解释:  ?9 {9 z7 c* Z. Z& ]
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
; V3 I) h5 B' EnReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
* v$ Y" p, Q8 r( U4 B返回值:
. W$ I/ }* I1 B+ |  y返回非0表示计算成功,0表示计算失败有错误
7 p. I/ P5 X$ U5 f/ h2 s. `- ~/ ~: y6 T. f$ \
* I& r1 Q$ G4 K; X5 ^; O

! y6 _! p) s' n' Q! h7 Q8 F  T程序代码:
9 o& P# \) @8 U3 u' c4 J- D9 L6 J. F; f
namespace fy_Exp{$ i! W6 @, S# \6 v/ {
namespace {template <class _T>3 S2 a7 \  z+ ~, u0 z
inline _T GetExpValue(_T t[], char& csym){
, @3 A2 U- X) @0 J: c    char c=csym; csym=0;
6 b2 e2 l. K% P( }; ~2 d1 _    switch(c){
( @& J# ?- x2 p$ B/ H; z' V8 d    case '+':return t[0] += t[1];
! e6 K6 s+ ^2 f9 o& |# M    case '-':return t[0] -= t[1];
! Z! X/ H$ A: w/ l" E- Z* l7 }6 R    case '*':return t[0] *= t[1];+ c# E3 q% Y: p* X
    default: return t[0] /= t[1];//case '/':0 U: R/ n. @$ _8 x8 `2 x
    }- P- P* `8 w) i  x( s4 {% b
}}
: z0 T& _; z; C% U' Z+ c5 Gtemplate <class _T, class _Tstream>* Z2 i$ p1 }5 K% A8 Y
/* _Tstream: inputstream, _T: get return value; F8 `1 r7 m) @; z; \
* Return nonzero if get value successfully */
# h) m& V& g1 _+ sint GetExpValue(_Tstream& istrin, _T& nReturn){% p! D& K, v  C) G
    _T t[3] = {0}; //雨中飞燕之作
8 T7 U! `) k' [* f+ A7 E    char csym[3] = "++";+ \5 b1 Y8 a9 S/ y$ w+ a9 B
    int nLevel = 1, nERR = 0;
+ T2 d# O# u3 I4 _/ E1 p5 h9 y- d    if(!(istrin>>t[1]))istrin.clear();
4 n0 x5 O% s% ]1 S5 d6 ^    for(;;){# f* W) i  V0 i3 n
        if(istrin>>csym[2]){& L" A3 \& Y, c/ W9 B- t. a
            switch(csym[2]){
6 W- ]4 ~) h& {% w8 G9 ?            case '(':
" W; j4 ]& f6 H" p7 R! q                if(!csym[1]){nLevel=0x100; nERR=1;}else" M: U" p$ ]$ w" k3 L
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;* z  `$ S* Q8 P" F; [6 f5 }
                else{nLevel=0x100; nERR=1;}
6 J6 v: K$ t) f4 W                break;
& x* I! h" w( w            case ')':8 T$ P! a5 F% y# J/ s
                {nLevel = 0x100;}break;
: R0 J" I7 z4 x* ~8 p            case '+':case '-':case '*':case '/':
3 W8 K' h& h1 {9 ?- F: C$ t                {csym[nLevel++] = csym[2];}break;
( [( Y4 f7 A0 ?) s0 o            case ' ':case '\r':case '\n':case '\t':continue;
8 ^! ^4 q  M; W4 f1 q" Q3 q            default:3 [+ G/ I' P- M2 H; ^/ v
                {nLevel=0x100; nERR=1;}
% e5 k$ s1 [7 s2 F% k            }7 P1 B0 k( Y& x0 p
            if(nLevel==0x100)break;
! }9 M1 d8 p% O$ l( o            if(nLevel&0x10 || istrin>>t[2]){
  b/ \, C' ]  w# G: }! q                nLevel &= 0xF;& T$ O) a4 K( s) \  R0 _+ k' l: x- t
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}8 [) q+ d* `) a& M
                if(csym[1]=='*'||csym[1]=='/'){
" c# O* A$ U6 z" b; O( s                    GetExpValue(t+1, csym[1]);
6 J3 {- w. B% |  b! T                }) n$ f) b1 t, w" ~, f7 P
                else{
% |, R' _- T+ ]/ ?7 W  c/ V                    GetExpValue(t, csym[0]);  `: F  x8 c6 I
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
5 H6 \) i! S5 }                }7 [  [) x, o9 c" ^. M+ F
                nLevel = 1;
: y6 o! e, k1 U7 c) z            }, }* j! O. E( E+ M0 z$ i
            else istrin.clear();0 H& p9 m% X, o  I: b
        }, Y3 J# x8 w0 v2 n# {. [0 ~" E
        else{nERR = -1; break;}
  ^6 q" r7 F. E& k0 j0 u2 T; C7 g5 l    }
" u' S6 S9 P6 ]8 K' v8 [) F5 G1 m    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);: M4 T' q% [7 H+ b9 r' p- X
    else nReturn=GetExpValue(t, csym[0]);
5 {7 D; ]; n. y3 @  a    return nERR==-1?1:0;* }; }# n% s; g
}}" |: y0 `7 H' t7 |7 d: r+ p5 L
! p: W1 {1 J4 L% l$ A& b

; t& _, ^0 L% {( i+ s+ S4 @' j" ?  q- U9 T% |6 `" D8 H% Y
函数模板使用示例:) N/ k+ t  [6 l2 b7 z% D& k
在以上那段代码的后面加上以下代码:  C9 m3 ?9 C& A; X# R0 a& m

1 ~$ Y) L! S9 @) b+ H: F" s+ l" r
& a7 g, [5 `* w: E% K
" O2 U5 _0 s8 {$ g! C程序代码: 8 O3 }0 ^- Y9 `. v$ R

; ^6 y6 K& O3 l' e#include<strstream>
5 {4 K$ x, W& D#include<iostream>! }' z+ d( w/ O5 ^- D
#include<string>
3 A8 n  t- r' z: busing namespace std;6 o; X# r* V6 g* |" e
int main(void)) t/ U! p9 L: P& M
{
0 ?. u% C; Y% [8 Z8 C2 U    string s1;, y; Z8 l' U- R$ r8 V- _
    while(cin>>s1)" c; [- T/ Q! ^8 z6 l
    {  `! K2 y# Y5 P
        istrstream isin(s1.data());! Z5 {, M" e6 ?' |
        double d;% S5 C) N, Y+ T. _1 c6 x( ^
        if(fy_Exp::GetExpValue(isin, d)): ?' s0 c+ c5 ^( E  Y
        {' q. G9 x: p* D# W" r
            cout<<d<<endl;
, |/ m" K, S: U" m. V0 C        }( r2 s- N% ?7 @' w& Y
        else
( h2 w: P8 A" Z        {! J+ x' X+ _0 v0 c
            cout<<"ERROR"<<endl;1 V! g! o9 A% T/ g
        }! a& ^  C" }7 Z. d2 K/ K
    }) M5 f5 L: M3 ~  h
    return 0;
9 d/ ], l2 E6 H}1 N' k6 u5 i, T; ?

/ @; y% U5 }+ g6 k' G8 F$ i  X1 y# W# m+ \. _4 H" y5 ^
然后编译执行就可以了(*^_^*)
  t4 g% K+ K- a2 T% N9 e' V; W; S其它:TC++上一定编译错误,不保证在VC6上也能通过编译1 P5 G+ W$ V* W2 i4 P+ O0 T6 o
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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