返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,* u( m  k! m' l. R6 m7 @
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式& L- P' b* \( T' l8 E
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
' {) D/ w) S2 n参数解释:
7 d9 X4 p8 e! `* t+ wistrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
% X% T% z2 b, \7 N. snReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
0 n" L9 N* w+ Y; H$ B返回值:. s7 M( ~; V! O" L
返回非0表示计算成功,0表示计算失败有错误
! d( @/ L# q* e0 F) P$ J  }. v3 v( G1 y
+ m) E% C6 a, @/ _% }: I

  W8 G7 X7 A2 q9 |( z程序代码:
+ l/ W# n* L9 _$ y3 @& n7 j5 p0 n: k
namespace fy_Exp{" e8 k+ W9 e$ H% n
namespace {template <class _T>
; c  \) Z% L  a+ [! F3 rinline _T GetExpValue(_T t[], char& csym){
1 h/ ]6 Q4 G% B5 q% P% Y+ T    char c=csym; csym=0;. x- I8 k3 k2 v2 m; f1 f& q
    switch(c){* c  V$ H$ {1 n  ^. J# L: M
    case '+':return t[0] += t[1];9 M$ r* O. U* V
    case '-':return t[0] -= t[1];! g- t- [2 l0 n4 I) q# t" H
    case '*':return t[0] *= t[1];. L" L0 y( C. R0 a: C) }
    default: return t[0] /= t[1];//case '/':
6 P7 N, \* {! k- u    }7 [' q' g/ d  r/ f" q
}}1 O7 |5 X4 C/ u0 p2 d4 ~/ c& K
template <class _T, class _Tstream>
1 r( h5 u$ k3 K+ n- l# k/* _Tstream: inputstream, _T: get return value: T* T5 N  l8 B6 D6 M
* Return nonzero if get value successfully */
# Q# r; G! T: w) ^# {% J) Gint GetExpValue(_Tstream& istrin, _T& nReturn){8 n  a0 J9 E  O( B) c
    _T t[3] = {0}; //雨中飞燕之作
5 g: R7 k9 f& ?; H: y; K    char csym[3] = "++";% A3 [0 |2 s* W2 z
    int nLevel = 1, nERR = 0;
1 e1 c& N3 `& [# e    if(!(istrin>>t[1]))istrin.clear();
0 `6 |' z) b. h6 Y7 ?4 a6 v    for(;;){* P: b1 Y& J/ C. O/ J2 W) X( A' V% g
        if(istrin>>csym[2]){% M# F4 O! w- W* a: |( g3 y
            switch(csym[2]){
5 O+ W# B/ i( {            case '(':
1 q. T1 I6 W) K  Q% _: u                if(!csym[1]){nLevel=0x100; nERR=1;}else
. v7 u5 q/ A! f9 N9 p7 C                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;; B1 O2 L9 o- `- ?2 o3 q
                else{nLevel=0x100; nERR=1;}
! r4 p5 G/ s  Y( I( r! z* S                break;+ F' I$ }1 W/ }5 s8 G4 J- z3 `
            case ')':
6 C: I6 S! ^# e$ E7 j, T0 u                {nLevel = 0x100;}break;0 h( T* g1 W$ Z' b
            case '+':case '-':case '*':case '/':
5 [6 Z5 F# M$ M. G! K                {csym[nLevel++] = csym[2];}break;; ~# K& }4 [+ o  z
            case ' ':case '\r':case '\n':case '\t':continue;) f9 N8 S: k9 S0 R9 y
            default:
- Q) k8 F. G( h0 F                {nLevel=0x100; nERR=1;}$ f. P9 @- Q- U" o
            }
6 E0 T) m3 R8 {( e  X1 g            if(nLevel==0x100)break;* G, L( S& |# h# h# d1 m% ]
            if(nLevel&0x10 || istrin>>t[2]){. {; f+ T7 }3 J( c: X( b
                nLevel &= 0xF;* f) |- O) m- ^5 {& d# L  x6 x
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
! M# N$ t2 O: S2 j; Q  Q1 M) w                if(csym[1]=='*'||csym[1]=='/'){; {! k5 L9 ~( `2 h7 o# s
                    GetExpValue(t+1, csym[1]);$ R9 Q: I' [5 ~. _% a' C1 F. Q1 x( u! f
                }% T7 G$ x, p& N* m
                else{
4 G7 O& v1 V0 ?+ _8 m                    GetExpValue(t, csym[0]);
% B  ]- {  X# {/ N                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
: O/ s$ L9 G" G2 J) ?% Z; K! k                }5 Z6 I) d' G# i+ ~5 m
                nLevel = 1;
, B; i& t  g: `- Q8 C+ Y4 C            }, e3 ?1 I# }& p+ G9 w2 w6 R. K' U
            else istrin.clear();% D1 @: g/ Z( @5 ]3 ^4 r6 O7 L
        }5 G7 x: `4 u% U. O  L+ v
        else{nERR = -1; break;}
  I" ]3 F+ H' m$ [* P: M% J8 C    }8 P6 S# o* g2 S' i/ p
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);( m2 X8 e/ Q' v$ m9 }5 [( N
    else nReturn=GetExpValue(t, csym[0]);
+ C% ^; Z: X4 ^6 w" D' g6 I2 ]    return nERR==-1?1:0;% f8 {# _, v/ @8 x/ H. o$ K
}}( s0 e. C9 ~% A. Z2 \) s

' b4 q2 d% |/ T: _7 p: U) I6 _) H* r, s8 b6 L* R7 u: i

' @$ `0 X& ~; O, J" u" L函数模板使用示例:) e1 Q9 t! g8 N
在以上那段代码的后面加上以下代码:
8 E% q( ~+ D. O5 U/ \% ]0 K2 k+ ?" K

) K% {/ Q; {# {& }. Q0 v
) U5 b  n5 A, x$ O; F: v4 p9 |程序代码: 8 V4 F# h. V) |0 Z

2 {3 k: y' P* x  p! T#include<strstream>
1 M  s3 w" R2 U& O#include<iostream>+ P. k. ]. d! p) n
#include<string>  L  Q& a1 \* r! |& Y1 }9 `
using namespace std;6 P6 u. k5 C9 O# W
int main(void)! Q& b/ @1 H. N- B
{# v; h3 R8 E9 b8 u" I9 k
    string s1;, z  b- x" D# _4 H
    while(cin>>s1)
; }* T, z3 k: D% }+ C6 N# e    {' W5 v3 |  j, d1 Y6 C
        istrstream isin(s1.data());
2 [/ _9 z+ X, \' d4 H        double d;% y5 l) {% s" U- d
        if(fy_Exp::GetExpValue(isin, d))
1 w4 Y) |4 j1 s) }; B        {
7 \3 h: O6 _: E9 A2 p. Q; [. D            cout<<d<<endl;. U6 {6 _7 j) f! d& W
        }
$ F, L1 h5 K7 d1 K9 j) C        else7 A8 t( J- }& j; G$ ?+ `" [# E  ^( m
        {
- m1 z4 J/ y: g' E- p            cout<<"ERROR"<<endl;$ n7 t0 B. F* ^3 I
        }) W3 ]5 g! [, V
    }) ]" S, K) P1 b8 j
    return 0;: o( h! M) Q0 |. m
}5 `1 Y1 j* t( C) O+ m- ~" S, A  W

7 Z# p4 V* H% @& C% K5 J1 K8 a( L+ E4 M6 A4 o8 A; W' |3 I" b
然后编译执行就可以了(*^_^*)! b. v) s! ^3 j  B# e0 Q. P$ G
其它:TC++上一定编译错误,不保证在VC6上也能通过编译
# O7 C/ J  y9 O6 h! V! S- K      建议使用VC7或VC更高版本,或者使用GNU C++编译

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