返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
: l0 D' w9 p4 u- Z/ N一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
3 P/ P% |! `) p! E: O8 |3 V. v) u  H只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
- p/ `. N5 S5 F3 o/ T' d参数解释:3 D$ G! N5 T/ H
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流4 p- H& c$ Z+ {& b
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定" S* ]: I8 N3 Y+ m8 u( R6 A$ e
返回值:0 H* v7 ?; p8 A5 ]) o0 h' y
返回非0表示计算成功,0表示计算失败有错误
* W: l  c& d$ \& g5 d
+ K9 E) d: p- p6 B  Q 2 V$ w0 b' b6 `

* b5 m3 X: S! N7 E程序代码:
  N: R/ B, q, [% q
* [* w  L# r7 Q6 `1 m1 j& r9 o: U' Q3 R. g% tnamespace fy_Exp{
! Z7 ^( Y+ L8 P7 L' w4 Fnamespace {template <class _T>& o! `8 a' C$ z
inline _T GetExpValue(_T t[], char& csym){+ }9 C# }4 M0 X
    char c=csym; csym=0;( D5 p. V$ Z8 ?- A- j
    switch(c){
. t6 m' R" @; w' E. ~5 Q+ W2 r    case '+':return t[0] += t[1];7 w' D6 C, y/ H5 B
    case '-':return t[0] -= t[1];
/ F6 d0 t# ?. z7 I. r  `* g; B8 [    case '*':return t[0] *= t[1];
9 }8 o$ m* r8 b8 c4 u' [+ A    default: return t[0] /= t[1];//case '/':& l. U4 t* `4 D
    }
8 q3 a3 D  I* E}}
4 R+ L/ _5 q: k8 \8 Y5 r! ftemplate <class _T, class _Tstream>
6 y) i; J2 U, }# t/* _Tstream: inputstream, _T: get return value
. v) Z# I# i$ H* Return nonzero if get value successfully */0 \% w( }+ F( s- h
int GetExpValue(_Tstream& istrin, _T& nReturn){7 h% s$ f1 x" }  n
    _T t[3] = {0}; //雨中飞燕之作
/ q5 q/ v) o8 M7 x5 I    char csym[3] = "++";
8 U1 u( j) g3 H; v! M5 t8 Z1 x    int nLevel = 1, nERR = 0;6 u+ Q: K. D. y* {2 g/ T! ]1 H  t
    if(!(istrin>>t[1]))istrin.clear();+ k0 L2 F% O  G( `6 f6 b
    for(;;){
% l9 \# X3 I$ x0 w" v$ f        if(istrin>>csym[2]){
# ^4 g/ d; R* E8 @            switch(csym[2]){, u9 F# _. r* H% Y. \# H
            case '(':1 Y3 m9 b' j# ?) k/ B
                if(!csym[1]){nLevel=0x100; nERR=1;}else: J7 t) [! f: i/ W: H
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
! G% D9 v* r3 _/ Z0 a                else{nLevel=0x100; nERR=1;}
. K* q0 _, H# t; H: z                break;
7 G# f7 Y: ?  D6 U            case ')':) B/ K7 m; Q0 V, i+ q
                {nLevel = 0x100;}break;
" k+ k( ]" ^0 y9 Y# Z  T, `            case '+':case '-':case '*':case '/':
5 ^3 X' T! _1 W' z                {csym[nLevel++] = csym[2];}break;9 ?7 F: W1 x2 C" V5 a8 ?
            case ' ':case '\r':case '\n':case '\t':continue;
% j: h2 G: q5 Y. Q0 a            default:$ R4 h0 @+ |9 P. x0 u$ a
                {nLevel=0x100; nERR=1;}
9 f2 F/ x. S, s1 q+ @' C            }& d# S' g& Q" q8 c# `
            if(nLevel==0x100)break;6 U, Y0 _* s$ r& m. Z
            if(nLevel&0x10 || istrin>>t[2]){
4 g3 o9 T1 i* e% b7 @: `                nLevel &= 0xF;! f1 @5 `- Y/ y
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
) m( k" z' e& ?' s                if(csym[1]=='*'||csym[1]=='/'){2 |4 \6 c3 l" {0 @8 |6 X) p
                    GetExpValue(t+1, csym[1]);
+ c' z: g0 r& e; Z! p( T& d6 j                }" l$ k" A8 |- P" ^  b2 i- s: `# N, L
                else{1 V$ [5 L( l2 c% ~. [1 ~
                    GetExpValue(t, csym[0]);
- U3 n" f5 ~9 [                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
+ w* }" \. @1 X                }# V8 \) r3 ^( B" R: F0 x* h
                nLevel = 1;1 `$ R6 a: ~  d4 @% ]) V: \4 u% U
            }
6 m0 W  a) A2 J# j& z6 Z            else istrin.clear();
# ]& L+ \, v7 l5 w7 m% W9 |! c8 G9 t, ]& c        }: r+ j  i$ c+ P0 J- {% p% `1 l
        else{nERR = -1; break;}
6 L/ L! O4 y+ A' c  g  Y    }
3 m8 S' K  q& f- K, q1 n    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);0 f9 m$ i7 K4 \5 W5 h; D; _
    else nReturn=GetExpValue(t, csym[0]);* v1 D8 |# z! m# c; I/ y
    return nERR==-1?1:0;6 O! b3 I! _/ J* S0 n
}}4 M  m5 l6 Q' h* M; a! B6 d3 i8 S
: M7 b% c# @" n& [5 K* d$ f+ f
; |8 x- T8 P4 S8 m# V3 V

4 `6 F' ~% ~2 ?函数模板使用示例:
6 {. W  c% ~: E% u2 L: R) L在以上那段代码的后面加上以下代码:
6 P9 f, X+ t# L( d3 q. e) \* N# h1 F2 l/ n; o% ^: S$ l5 L

: s0 @$ J; R5 S7 |4 R# s
5 [# s$ B: \1 U" Z; U8 N程序代码: 7 ~- \) S8 J8 P  |

) Z, H, X9 D5 y/ G, \#include<strstream>
& o, s" q0 g+ g  R9 q# r2 x# {#include<iostream>
) S( s: {5 a' _! r; }1 H6 L6 s#include<string># {9 H0 H' p3 A) i' V% L
using namespace std;
- S! X0 p6 ^; m- [, Dint main(void): h: j" _9 a+ `8 c+ D, T5 r- J% g) T
{
6 ]: @5 [, r! |    string s1;/ C9 y1 z+ O: q
    while(cin>>s1)
& }0 }+ B# P1 y2 Y  r    {) U5 q* Q. f9 s3 ^( H0 @
        istrstream isin(s1.data());6 l( X6 [' B! c- Y+ N. t4 \3 S  t
        double d;
& [& a. ^) l% B; R$ l0 e, A& @& `        if(fy_Exp::GetExpValue(isin, d))- R" w7 W8 V. q6 T4 ]2 n# P
        {
8 g1 @' {8 ?" p  B; I! _& i            cout<<d<<endl;
1 x  ?: d9 v! e) a/ d# g8 s        }5 u% k/ u; W$ E9 v
        else* W0 L+ \& x. V( I
        {
+ B, e* y: L; q8 Y7 a7 o6 h3 [            cout<<"ERROR"<<endl;
# s* b- [6 e$ u% W" i        }
/ A" S* q" i. h: K4 V3 \7 c# l$ [    }
2 i$ u, r: c9 T* K; z% Y    return 0;
$ U- C& J, |- G$ A}" U% y' p: ]( B5 Q0 ~. j
4 p+ G  x  m' ?

( z1 g8 r: Q1 J1 L" L( S/ S然后编译执行就可以了(*^_^*)
; P! S' e3 l9 M$ y$ P其它:TC++上一定编译错误,不保证在VC6上也能通过编译
2 q6 V+ a0 y$ z& c/ g) E      建议使用VC7或VC更高版本,或者使用GNU C++编译

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