返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,5 y8 H* `  |; X& d
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
# k4 h' N3 W% l: a" L只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)* Y$ v' f/ m4 D& V& C
参数解释:
' O+ U3 ]; D! q$ F/ x: Ristrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流5 P  w! B1 K0 o$ c0 C
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
1 |6 n2 w$ K8 ], N/ p8 O返回值:
, H3 F6 k& g' @# y& q  l返回非0表示计算成功,0表示计算失败有错误
' Q- F# A1 r* M9 w4 c  |" n' j! S  R4 L4 U% J0 \1 U0 x
$ u9 ^% W0 q' S# n2 h; V% z$ A

8 s2 v: o8 P8 n& |6 E程序代码:
- ^* g5 Q6 w4 E0 E/ G. T1 J1 t- t7 I. t' S% \' d4 ]# N
namespace fy_Exp{" x3 z/ y; \0 b" X+ o$ y
namespace {template <class _T>
3 R$ ^2 ]+ n' s, X8 g: |9 O% Uinline _T GetExpValue(_T t[], char& csym){
' f. q7 p0 p5 a1 h    char c=csym; csym=0;! [4 B& ^. R( }3 k6 K+ d0 I7 w
    switch(c){
9 ?$ ~0 J2 m7 \/ x2 Y    case '+':return t[0] += t[1];" j# y7 P9 y% E7 l
    case '-':return t[0] -= t[1];' y# [! e; ]" e$ K$ ^. k: M1 y
    case '*':return t[0] *= t[1];- T+ o- n# a5 i( q- q# R( Q
    default: return t[0] /= t[1];//case '/':6 F, H) E3 T6 ]' d' U
    }( s' Z/ m9 ]% P, v
}}
3 z& N1 j) e0 T9 Y, Y* E6 O9 {template <class _T, class _Tstream>5 J* s/ |( ^' m3 H* S6 a( L
/* _Tstream: inputstream, _T: get return value+ b5 R% R, i8 S4 i
* Return nonzero if get value successfully */! T8 n# I8 _- z- `8 s7 [8 N
int GetExpValue(_Tstream& istrin, _T& nReturn){
  }6 a1 O  \; I2 Q; }( u1 U    _T t[3] = {0}; //雨中飞燕之作, P  K& A& L% f# A0 r
    char csym[3] = "++";
: }5 ]" \+ K: u7 f# Y6 V9 V! X    int nLevel = 1, nERR = 0;3 o) c- t+ O7 f4 X9 Z
    if(!(istrin>>t[1]))istrin.clear();# Q$ o! I1 |# t7 C3 E9 t
    for(;;){
. l$ W% d& r/ Z! X  e  z        if(istrin>>csym[2]){! Q0 v: R  ^1 L3 u
            switch(csym[2]){5 X% s2 v3 ^7 `/ Y1 `9 G$ s
            case '(':
1 [* U2 z9 O" e2 y8 H/ H- ^                if(!csym[1]){nLevel=0x100; nERR=1;}else' ]" ?5 }5 ^5 ?$ X: ~& f2 T7 E1 F
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
1 P8 w+ n  z- L                else{nLevel=0x100; nERR=1;}4 E! b+ v7 s9 v% Z
                break;7 {4 R( n- L. Y7 V
            case ')':
3 T( j% k& g6 B. B9 X  {                {nLevel = 0x100;}break;
$ W  H+ B6 z0 C+ i+ G$ Y# i- D+ K            case '+':case '-':case '*':case '/':
0 w' n7 u  [: j: q% A: d( Q                {csym[nLevel++] = csym[2];}break;
$ b1 S9 E: q3 N8 e& m% v            case ' ':case '\r':case '\n':case '\t':continue;; {) \: m: \% L1 }$ p7 j% [
            default:
1 ~8 v0 P- X9 J! m6 m                {nLevel=0x100; nERR=1;}
1 e0 [$ ?% G9 L- d            }% W  R4 h: M3 m5 ^/ E; r7 N/ N
            if(nLevel==0x100)break;
+ Q' n1 K1 E3 O% E7 i. K1 U            if(nLevel&0x10 || istrin>>t[2]){
1 j& L! |5 F, F6 ]# }                nLevel &= 0xF;: Y- N4 r% G) y9 a
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
: K$ w3 t. I9 p7 i- r8 m                if(csym[1]=='*'||csym[1]=='/'){
0 a- c, o4 U# w; G) }/ |1 K                    GetExpValue(t+1, csym[1]);' \' q1 M$ q$ X2 t
                }
; b! Q! y1 n; l                else{
$ j0 F- x6 J2 i, o, x. U                    GetExpValue(t, csym[0]);
4 d% V" G2 ^% _; E8 |: N1 r" F                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
2 E3 u3 S+ Z2 h- q                }
0 e! i* Q& C" l; f. V3 X                nLevel = 1;+ S6 [! M0 }4 F, z2 P
            }: p% U6 T  @2 \+ O
            else istrin.clear();' F7 K9 p' L1 t3 l! t
        }6 r+ i7 e7 n, Z$ N! R6 h, v
        else{nERR = -1; break;}
& \. [1 w. n! K$ e, {, h- |% e    }+ o) R4 B2 ]8 w( F
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);% J" `& }8 C1 j6 E, z4 n
    else nReturn=GetExpValue(t, csym[0]);8 @  @- f# n) v/ `4 n( l
    return nERR==-1?1:0;5 I6 P* b! ?5 P; |. n1 i
}}$ z  B& Q2 l$ D, l, z5 m
; t# y% A/ e) R$ `8 r, L

8 c( k. w* S8 o8 x
! G6 c7 ]# g& V7 V3 J函数模板使用示例:- r2 L; ]# v0 k; ~3 G( B
在以上那段代码的后面加上以下代码:
" q( `  }7 w8 N6 N- l* w
$ C! J4 H0 B" T6 a" w5 K* C
" [& n! k  m) {# P! F: E
6 i3 G, w9 G0 B3 m0 a" ^9 d1 ]程序代码:
7 e& S  e$ O2 l. @/ p$ x$ C  v. w3 d/ r- G) R7 R8 L8 h) N
#include<strstream>0 r. Z; R- q4 s# u7 f! @' d
#include<iostream>
5 D1 T1 v, g8 k# ]4 B) k/ `#include<string>! w  P4 R& c3 |' ]
using namespace std;
' m( a# K- _2 d5 [: o0 U4 d' Zint main(void)  t' w0 r/ l) z" ?
{  _9 O! D  B6 V7 o, r/ ]
    string s1;
1 g0 I! B9 v. n/ \5 X    while(cin>>s1)5 j3 _" ^- r- e3 i% z
    {: c+ U* J3 i7 M5 H/ O
        istrstream isin(s1.data());
! {, ?9 ?8 m, M8 B! J4 H        double d;+ L6 B$ Y7 y+ J1 t
        if(fy_Exp::GetExpValue(isin, d))  [; O4 h2 v- U. u
        {5 l; I: s/ L) C
            cout<<d<<endl;5 J+ \  _, ^* j  b
        }4 z5 W2 W" O8 F$ k3 D  _
        else) |/ [. H# p( I: v2 D4 _( b2 k
        {
7 m( L4 t0 b: t" E7 _) E6 @            cout<<"ERROR"<<endl;
- w; w, |* K7 y! I7 E" q% k4 M  f        }1 C* p. O/ {( ]: c& n: [
    }( K4 u% a7 H1 h9 h
    return 0;3 i& s) {6 u7 T' @/ ~; D! d. F
}
1 Q; h% f9 z$ X
1 u" F+ ^. S; o8 z0 e( @6 N; i8 O/ w. H8 z+ x4 b; j% o! l8 B  I- m
然后编译执行就可以了(*^_^*)
1 c6 ~" S# {& u, Z/ {' J  H6 u其它:TC++上一定编译错误,不保证在VC6上也能通过编译
3 X- Y& a' Z% [; W      建议使用VC7或VC更高版本,或者使用GNU C++编译

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