返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,: F6 J& Q, f: o% M" R/ z
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
9 w; U1 }6 a0 j( r* T  m$ g0 n只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
9 l: c$ L. J4 Y" P参数解释:# k: h- l1 i9 Z) M) j" i6 q
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流3 I2 y6 J6 X# {7 B6 t# }
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
6 Y4 U8 \6 {4 E* @/ X- j9 v+ J7 T返回值:  A9 S  P5 H4 P3 u# y+ C$ f
返回非0表示计算成功,0表示计算失败有错误
+ l9 @% [- j( y, P6 g
' ]. P3 `' ?% Z4 c
! R/ f' g8 [# ~0 k/ C
5 V  J, A, h1 y7 A; |程序代码: ! {% x1 m7 C& ^0 z' v
+ `, [, k# _( p" W- ?
namespace fy_Exp{/ `: A$ P' P. K' N' l
namespace {template <class _T>: h! ~" l& [) x+ m. o) F/ v- c) ~
inline _T GetExpValue(_T t[], char& csym){0 s3 \9 d+ D: f( }
    char c=csym; csym=0;
9 g3 i& V9 w1 T/ E$ V! M    switch(c){
* ^2 H& s. N! w. @- S; S7 z/ b    case '+':return t[0] += t[1];* M, w3 [$ p# x+ y
    case '-':return t[0] -= t[1];
8 Q! l+ b0 w, H( P0 X$ d9 q    case '*':return t[0] *= t[1];, ?8 g( b: f0 ?  v/ }; C
    default: return t[0] /= t[1];//case '/':
8 L+ e9 I, _  p7 n- S    }& f. h+ j6 g0 E/ _1 l: U/ J
}}; ]' m, O: s2 K2 B2 V
template <class _T, class _Tstream>, J6 X7 p8 s, b! Q* @; B
/* _Tstream: inputstream, _T: get return value* P+ c$ t# H. t2 n: y9 ]
* Return nonzero if get value successfully */
; |% X1 w" \) N3 N! O$ b& F& y, L4 hint GetExpValue(_Tstream& istrin, _T& nReturn){
/ o! l1 c, S( G& ]% V) H    _T t[3] = {0}; //雨中飞燕之作. l- o/ I8 `: V1 `
    char csym[3] = "++";
4 A6 H$ @$ G, i4 Q5 K9 i    int nLevel = 1, nERR = 0;4 Z+ o& w+ N/ v% x. S6 X' h
    if(!(istrin>>t[1]))istrin.clear();
- }5 D, H9 R7 E" \1 s$ E    for(;;){
- j! h' w  i6 t        if(istrin>>csym[2]){
/ d& o0 y: `% G            switch(csym[2]){5 H, R# v  E+ o5 u4 u8 [2 w
            case '(':
( l" D/ O; d9 p# l                if(!csym[1]){nLevel=0x100; nERR=1;}else
+ {7 w- T1 f, [' b                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
! S+ w: K7 t1 C4 D                else{nLevel=0x100; nERR=1;}. }' f: V* I6 b* i7 E8 \
                break;. m0 X" D; w  @- L
            case ')':
* Q2 P7 _* ^! v( p# L) |                {nLevel = 0x100;}break;
( e7 Z" j. S' l* S8 n/ ^            case '+':case '-':case '*':case '/':
+ |5 @6 _1 T1 O, s3 w: G                {csym[nLevel++] = csym[2];}break;
4 F( R3 f. T/ r& i+ I/ l, M2 r            case ' ':case '\r':case '\n':case '\t':continue;
, z! r& {; H9 @0 O            default:
6 P0 Z2 R( q8 ?                {nLevel=0x100; nERR=1;}& o) C4 w; t+ F% I; V5 G
            }
! E  _7 [$ L; i% E            if(nLevel==0x100)break;
% m; D) Q9 E$ ]8 B) J            if(nLevel&0x10 || istrin>>t[2]){0 m+ ^/ X9 D* r8 U0 W5 t4 G% N1 S1 g/ ^
                nLevel &= 0xF;; M6 G  Q  R8 E: r- Y
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
1 A" y, X& |1 {. b( L; B                if(csym[1]=='*'||csym[1]=='/'){7 V5 |! X$ b/ [) ]
                    GetExpValue(t+1, csym[1]);
7 Y  R3 t4 s; x, B                }
6 b! t, @, X$ L( y; S( g! V                else{
9 i6 j& E8 D" ], j                    GetExpValue(t, csym[0]);% z6 M/ R  f8 _' E
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;5 J8 H9 h* P5 \# Z) d0 J
                }
* X9 B) E- ^* w* P                nLevel = 1;
& v3 Y& d8 y4 b2 N            }7 F  f' n) c( z  A# }9 [0 \5 G, n
            else istrin.clear();
# ^1 v$ C: k- n+ @& c        }0 ~8 K+ x& F9 V& I$ C) k' i7 Z8 o
        else{nERR = -1; break;}; ?' B+ T5 ~0 w7 `
    }
' x6 Q! T$ K/ v; x    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);* v( j0 e6 L& ?# J
    else nReturn=GetExpValue(t, csym[0]);; `$ ?5 X0 q9 r6 w" e! u: r0 F
    return nERR==-1?1:0;
( w/ F$ ^% S1 R# H}}
* H* E+ F/ B& M: l( @! O! Y1 X8 D9 s6 a% u! X! G3 f  V4 L$ F

* \2 n. Z5 g  y/ i* k' r& w
0 T* {' O" X# Y. r$ t/ E8 J: y7 H函数模板使用示例:. R) s! U; O* j, \2 Q
在以上那段代码的后面加上以下代码:
6 M9 d: m; F( `( u$ D* N9 C1 _$ d  }2 a2 F9 C. t. _/ e

! f1 s6 ]. i# v/ }- f& f6 K8 F4 [0 ~  L
程序代码:
% I/ O  [: X) p( t4 i& D
  J5 e0 E* Y/ T5 I7 w% M; R% k2 B#include<strstream>
4 N5 S, [4 e. o0 e, a# t3 ?7 P#include<iostream>
/ [2 W9 z  q' u# _#include<string>
( }( e8 c6 w& v7 @) }using namespace std;$ |' {# Z1 J; t' l( v: i' w2 D
int main(void)8 t, r4 Q) [. T0 E5 K# N+ N% s
{0 K: q3 Q/ v# X# [
    string s1;1 g5 ?  I8 W9 H7 T! K
    while(cin>>s1)
% o. A9 w' {! r0 c9 w+ ?    {7 N+ F( J( `& d
        istrstream isin(s1.data());" I$ {/ ?+ ?1 I# `0 E1 `" h. L
        double d;
# t. W% e+ P& [+ S" I        if(fy_Exp::GetExpValue(isin, d))9 h+ I8 E; E; \6 s
        {$ E8 k7 H- X; C, D& S7 P1 A0 W
            cout<<d<<endl;
8 V' s% N; z, e& C) ?  ]0 {        }
! K+ n" p/ Q6 N, D1 e        else
4 l# i% u2 `! N% C6 s0 f        {1 |0 k9 I" z7 U6 z
            cout<<"ERROR"<<endl;
2 v# m4 W+ c( W2 n) q* ~; ?: T        }5 [6 R) c# E( g. i8 n8 ]2 N8 ^
    }
: n, L9 C8 h  s0 z    return 0;9 L7 m0 B, T& I) c/ C% v
}, m& W% G" d  K. ]8 n# X

2 h3 j6 r2 q% D) p% k3 Q7 y
2 T7 ?/ Q& V. I! @( e然后编译执行就可以了(*^_^*)
# s; T/ y, U. [2 s, V其它:TC++上一定编译错误,不保证在VC6上也能通过编译
# X: \% e, ?7 E8 F* X      建议使用VC7或VC更高版本,或者使用GNU C++编译

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