返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,1 h+ |9 \" W0 R) `- T! z/ o. j2 r- [
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式$ o2 c' _! j5 f5 M0 q) F
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)% B& a  j  \3 g6 k% q: X
参数解释:
1 a' P6 F/ ~/ ristrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流/ Y5 x+ _( C. M0 Q- |
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定' M* ?* A& y6 q; m
返回值:, L3 y+ {/ r, I) b( U
返回非0表示计算成功,0表示计算失败有错误
2 D9 `4 u: W- f  C$ }- A0 a9 K7 V# |8 B* l5 R

, j! E: M- U  j& N% m) o. O! C1 p7 N5 O: i! a
程序代码: * N) q& m5 Y; l1 t; p) W

/ F2 G& w% |6 P4 [1 g) _( }namespace fy_Exp{( P$ Q+ `$ d& L
namespace {template <class _T>% I0 e3 K( a0 o2 b( @% }
inline _T GetExpValue(_T t[], char& csym){; U! b- h1 M; Z' _* S
    char c=csym; csym=0;. j; ~3 n9 N1 f- t4 c, |6 P
    switch(c){/ `/ e" y( X/ a
    case '+':return t[0] += t[1];; c) Q) ~7 z# C/ R3 O
    case '-':return t[0] -= t[1];
; f& ^4 ^1 |, {9 b6 @% U    case '*':return t[0] *= t[1];' \: Z- }! u, z
    default: return t[0] /= t[1];//case '/':
+ E8 @3 @+ O) ]/ x    }
9 Z5 V" |) B" y% n/ r' a% W}}
  F! H) a5 X4 |6 v+ rtemplate <class _T, class _Tstream>
- N/ o! m: D/ L9 u/* _Tstream: inputstream, _T: get return value+ n& E$ W9 \$ ?9 O0 \
* Return nonzero if get value successfully */
. b  `( Q! c- v, ~int GetExpValue(_Tstream& istrin, _T& nReturn){
' x, t! h; E; V  D( f' L    _T t[3] = {0}; //雨中飞燕之作. l" i5 L! f* `- n- J: g2 t
    char csym[3] = "++";' s. \9 Q/ J) V. a/ Z
    int nLevel = 1, nERR = 0;3 z$ S# C4 j$ O- b" m8 O6 K" W/ s
    if(!(istrin>>t[1]))istrin.clear();+ A: ^) x- [' S# e" w5 U
    for(;;){' m& p# m! K; p. N- p: A3 m
        if(istrin>>csym[2]){) s& e' R: {1 e" l  }
            switch(csym[2]){
  _( h$ Q' E9 y2 m3 V( W# A6 |+ {            case '(':
: b2 M3 u, `: p1 _                if(!csym[1]){nLevel=0x100; nERR=1;}else
1 W4 V: N4 u& k8 S, ~0 ?) f! ]                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;3 c4 ]* Z' C4 }1 n- s$ D5 r
                else{nLevel=0x100; nERR=1;}" {3 n3 @) U6 o
                break;
* B0 q& p( `5 l0 e            case ')':
5 L6 B) r, F0 s0 d+ L: P                {nLevel = 0x100;}break;
  n2 N. P2 T7 a0 Y; h6 N            case '+':case '-':case '*':case '/':
8 L. j' o: c; c5 F7 u: `  W# Q                {csym[nLevel++] = csym[2];}break;6 `2 M3 p! w& w/ w$ c3 c
            case ' ':case '\r':case '\n':case '\t':continue;/ u7 t- P! s& l8 b. e1 C
            default:! z  z3 C& F* \7 O, W; l
                {nLevel=0x100; nERR=1;}% y  A( a3 O: w* t% W) f
            }
8 c+ y& @  S! I% r9 @* D3 n            if(nLevel==0x100)break;' T& i2 F1 z) O/ X( O( W
            if(nLevel&0x10 || istrin>>t[2]){
! ^  f. f3 P; M8 q1 x                nLevel &= 0xF;# X0 W9 c, Z6 g4 E" I9 B6 ~
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}4 d9 ?# h  Z& p( |5 I; `( j: ]
                if(csym[1]=='*'||csym[1]=='/'){, ?! F/ t2 W- J" u9 y9 B
                    GetExpValue(t+1, csym[1]);
! q! x/ }7 ~7 G. b; ]* @; ^                }
0 {4 g0 W& {# D0 }. y/ U% u                else{
* v0 W3 F) o2 r- O- \2 B3 S8 ~                    GetExpValue(t, csym[0]);
7 l' a! O8 O% p                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;4 @  W' d- C# z, [% G" W& i
                }
% Z$ I  Z! y& O6 M1 g                nLevel = 1;' s$ C/ R* [$ }: q  q, T
            }- z- l3 n: M$ D2 ?) U
            else istrin.clear();6 P' C8 ^/ I- b& G& J
        }+ d% J: K& E6 x
        else{nERR = -1; break;}+ ?" R1 k/ _; A+ \9 Q
    }4 y* y3 F) W( [$ W/ X: g  W4 k0 i
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
) o; e3 K# U5 |0 |    else nReturn=GetExpValue(t, csym[0]);
* f7 X: M  U7 t  ~. B! m    return nERR==-1?1:0;* `& F9 Q: H6 X# u/ F
}}
4 x# i5 c, a  z% P4 U- X& U) A, R" A4 s+ q' H

' ]7 \0 d7 b1 V+ K  G- o9 M1 A* t0 H6 _( V
函数模板使用示例:- m6 {" n5 v' T1 G+ z3 O/ ^+ w
在以上那段代码的后面加上以下代码:
+ {0 {: p+ f# c$ j
7 q, f" a1 n8 R; R; s7 y # h) p( G% X& L- n

# K9 i" b$ g! n8 R4 p5 G程序代码: 3 t8 B9 ?$ K' ]  x+ D3 y4 Z% [$ z

& i; R. O2 d/ l: u% z; h9 d: o! l#include<strstream>
/ D, p/ l; L4 L7 w+ H; f8 M* b; B- I#include<iostream>
9 \' c/ S/ Y; U  B# Z$ z#include<string>
4 B2 A2 t. L; E1 ?8 ousing namespace std;$ n: B( Z6 b# z1 H, Q
int main(void)* Z- o5 @* k8 I" D" E* Z
{+ q4 ?) {% y( n! O: v7 i7 y$ ^- c9 J
    string s1;
1 z$ q5 k" M: p    while(cin>>s1)
" I" M0 _1 P9 m, I  h6 ^# {    {
8 L% _. w- i) ^5 H        istrstream isin(s1.data());; R1 n! b( ]4 d: M$ s; r3 U
        double d;0 C, t9 k6 \* \+ S
        if(fy_Exp::GetExpValue(isin, d))
% G1 R1 U" g& @, S. _( [        {
, B8 G0 p1 z' U9 J8 g            cout<<d<<endl;/ q. ~6 Y. |& r" ^. y9 m
        }
* p) u3 ^) x1 T2 N2 ]% R* E        else
1 V" L* B2 v' f- O/ @6 K6 S% L        {
4 _  E0 [, n; \" I" T            cout<<"ERROR"<<endl;$ ]# j3 L* j4 ^+ v0 H
        }
2 v+ N7 A; O; j; L6 B    }
: O% _7 @8 }% s% P! t    return 0;! V5 T6 h( _- s8 ]
}
; a" d! I/ I4 v+ X0 K# k! ~' V6 m0 v: \3 ~$ i* H1 w
' x% {6 |( P7 Y  k! t5 o
然后编译执行就可以了(*^_^*)
3 Z) e9 R4 S7 C8 K3 b5 i; ?其它:TC++上一定编译错误,不保证在VC6上也能通过编译0 Z. o# e  ?4 i  s2 y7 w8 E
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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