返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,3 \8 P% ?; W: n& l/ T5 q
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
7 `5 Y0 z0 y* K7 q只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)6 u1 {; k1 u% U* f
参数解释:
% }+ C5 q0 y3 f) q# p$ u( kistrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流0 W6 z1 y! b9 O: f
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定7 q. F* V# c& k$ n
返回值:( P- p3 |+ ]" o6 d# e9 A
返回非0表示计算成功,0表示计算失败有错误9 e6 s6 \# q) x$ C( j& @) ?- A

, t2 X4 f3 ?2 i! [
6 z) j$ O2 O. p  l$ c: {/ A/ c
/ g8 X3 Z. O9 q/ Q* t6 T( ?" r8 i程序代码: ! m8 O  V! P: C+ _1 J  W
9 i9 U9 W/ {3 D5 b) G$ e6 O
namespace fy_Exp{6 D6 M* @4 U  I1 j6 j4 X
namespace {template <class _T>
% E) W/ u8 k* ^5 J; Sinline _T GetExpValue(_T t[], char& csym){8 G0 c' U- P* V  r0 K
    char c=csym; csym=0;# Y, m# S" s1 Z8 n8 H+ ?
    switch(c){0 U& j/ i# a8 d& o6 |5 ^
    case '+':return t[0] += t[1];6 |3 B3 y4 g1 r( t- {3 X  c5 a
    case '-':return t[0] -= t[1];
5 g7 ~  W9 B, }4 ]    case '*':return t[0] *= t[1];# X/ W5 O1 x/ N' H, k
    default: return t[0] /= t[1];//case '/':
: |+ k9 o/ h$ n2 R    }9 l+ r( W3 z1 N
}}& F3 x# Q; w: N4 z, M* a
template <class _T, class _Tstream>
3 U5 L# ^& L. _5 t* O. d, Q/* _Tstream: inputstream, _T: get return value
) Y7 O4 [* _% m; Y* W- n; _* Return nonzero if get value successfully */, C) c% Q5 n! b; e/ t
int GetExpValue(_Tstream& istrin, _T& nReturn){: ?2 {( }+ y4 R, @# i, _# O
    _T t[3] = {0}; //雨中飞燕之作8 O, w2 o9 ]  L! h/ {
    char csym[3] = "++";  e$ r' E  f, S/ e/ u# V0 @
    int nLevel = 1, nERR = 0;& {- i" X: A  }3 w) [/ V/ |  o: t
    if(!(istrin>>t[1]))istrin.clear();9 e  n% p% b0 o1 K
    for(;;){: s2 p1 ?9 M; S/ W
        if(istrin>>csym[2]){& [2 n5 J  ]3 P1 p
            switch(csym[2]){2 F6 @- b5 d+ d. x/ T* X9 f
            case '(':  q( [0 l% X' ~% ~, i# r  W
                if(!csym[1]){nLevel=0x100; nERR=1;}else
3 O4 z4 H7 @8 ~+ L2 K3 V) B1 z                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
% p6 h, i7 I* Y" ]% ], b! ^                else{nLevel=0x100; nERR=1;}
4 S4 w) p1 e  v1 A* i0 N                break;
( ?2 u) C. e- q+ |3 g            case ')':% m4 j  m, t( O4 {6 _1 e
                {nLevel = 0x100;}break;( M6 D' e# l- D
            case '+':case '-':case '*':case '/':: }( w% O" l, J
                {csym[nLevel++] = csym[2];}break;7 O6 c5 Y7 S. g: c6 j0 c. X  ^, ~0 S
            case ' ':case '\r':case '\n':case '\t':continue;/ c3 [0 V5 k+ E! H# w9 t% N0 m1 l0 x
            default:, y3 a! l$ V" K3 R7 `& Q- m
                {nLevel=0x100; nERR=1;}
% x, k# J3 N- ~9 c            }9 U) e0 V# @6 [& T+ ^6 m
            if(nLevel==0x100)break;
+ v# n& N9 i3 N: `            if(nLevel&0x10 || istrin>>t[2]){
4 v3 d2 |" I& l( ]) c8 S4 H                nLevel &= 0xF;3 s" A' |6 \" {; v; @; M
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}, @" v2 g# b0 E. v. p" k# F
                if(csym[1]=='*'||csym[1]=='/'){# n$ n+ h+ I6 m% E$ y0 S
                    GetExpValue(t+1, csym[1]);& a* k9 Q- ^: {- o+ O3 V
                }
" _  y5 x& b3 B7 M                else{
& G# f; w7 A1 e& G0 R) G2 E                    GetExpValue(t, csym[0]);" B9 {. f$ g, s- T: _0 f+ A
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;  H* ?( z! |# V- i8 J, H
                }" z6 w# E& f* e8 U5 }" w( M4 _0 M7 b
                nLevel = 1;' r  c: b. M" G' [/ D8 h
            }
4 Y/ h( P" b: t            else istrin.clear();9 ?! p) t1 k" g
        }" P. K/ t1 _( `* q
        else{nERR = -1; break;}- H; s, D6 u0 i1 ~! ]" _
    }
1 K1 @3 a5 V+ Y    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
, G# M$ c1 I: p) d1 \    else nReturn=GetExpValue(t, csym[0]);
' {: V$ B, m' k2 z2 P3 n    return nERR==-1?1:0;
5 e# n/ n( A- r) l7 O; Q}}
# X9 b$ B+ {2 B7 A$ g/ o& t1 l6 i. v4 e, A2 n9 U( t% P! Z

1 l% d8 O; P2 |
; F- X/ J2 v( y& {; L; H函数模板使用示例:
# [/ ~6 [' y5 a0 G在以上那段代码的后面加上以下代码:
! U3 ]0 N! D7 U* d( b" q3 p/ M
. x3 r- y: z+ N" t
, ~( e8 O" X) A0 v% w% o1 X8 R, L2 V  `, G2 z: M' U! o2 ^
程序代码:
. _' `: \5 q1 \1 R% O$ h% h+ T2 S# u0 h5 T! q! J4 c& E
#include<strstream>
# D$ `* Y) }; y! c3 Q#include<iostream>
4 k. b3 ?2 K3 E2 A#include<string>: c6 w" u) ?5 U% X4 I4 o/ C. s6 r
using namespace std;
. u1 D6 N; L% i8 o9 l0 @int main(void)4 y; Q% u4 K4 L& [
{
8 L$ l5 z+ g$ l  W$ d% G7 V1 M    string s1;
# O  d  g+ x4 z    while(cin>>s1)
6 }+ [  f$ V  ?- M4 V    {# g6 {  A. l9 @, n% @2 b
        istrstream isin(s1.data());
8 K' {5 j# K( g! |) ?$ r& \; l        double d;& j- d. W% J) L
        if(fy_Exp::GetExpValue(isin, d))% O  R$ J' s( I; A/ Z, t/ v: e
        {
5 M) ?  U. q5 s# O% g# y( v            cout<<d<<endl;
% @* l% {8 W1 h: `4 K( k" `        }
! T$ q4 z) ]9 h        else& Z; E4 z5 o' \" f- b
        {
( }0 f4 X, N9 O* {! f- j3 d  i            cout<<"ERROR"<<endl;
9 s. Y3 C1 P- f0 E8 Y1 Y" S/ K        }/ e3 k, N  B5 T' |* l1 U
    }- p  E9 ], |& H8 B6 F
    return 0;
! Z% ^2 m8 s7 l4 G/ V5 }4 a- j$ ?}
6 q0 j% w) C$ X, G1 `
4 S# N. Y& p& g7 Y6 \$ g, o
* `9 X% F% }' X4 m) p, W$ V. Z然后编译执行就可以了(*^_^*)9 \. c% o8 n" j  @% b% ^
其它:TC++上一定编译错误,不保证在VC6上也能通过编译& [$ k# M# R: }# W$ K- B/ ~
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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