返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,8 ^5 ~9 h2 ^  Z
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式1 i4 n4 n" b: t% g$ |3 F
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
! Y9 Q/ W5 r1 `3 x7 s: o+ Y# @& t5 C4 @9 u0 `参数解释:
- v/ w, t8 _0 ^  Distrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流4 r; ~; s) S. ^& j9 N) ^# ~  B- a
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定/ e# @( S2 ]9 T. d. j
返回值:
2 i' I( }- k! d返回非0表示计算成功,0表示计算失败有错误
5 E3 B  ]9 {" f  C2 x% C: @: n: q( d' G* v' [1 X* t

7 u3 @- v2 d; ?6 @, ~# ^. Z" d4 a5 y# S# U. P. \1 F
程序代码: & z2 U" M2 L$ M: h" \9 I
) j& ~1 s- m. _* O
namespace fy_Exp{
- l5 {8 T& S$ }# k6 c. x" hnamespace {template <class _T>' O5 u/ T, r+ U# |' l) Y5 q) m
inline _T GetExpValue(_T t[], char& csym){
+ w' |  ]% B- W- D* K/ J7 }    char c=csym; csym=0;
9 t' N7 b' i7 E    switch(c){# W( s: t  j# T
    case '+':return t[0] += t[1];* R' [5 L6 t$ F6 Q. y5 ]$ u
    case '-':return t[0] -= t[1];
- F' {9 W! L  q) s) m/ A    case '*':return t[0] *= t[1];
, A2 g7 l9 D" n+ }5 g- M/ |5 ?    default: return t[0] /= t[1];//case '/':% l4 Z  [4 \4 t! o. G. T
    }% G$ a' Z8 _) A( ?
}}
7 _/ c0 Y. R/ a5 E6 E. Ptemplate <class _T, class _Tstream>
9 |3 H: g" S  O7 u3 `; B/* _Tstream: inputstream, _T: get return value( Y, f4 m. C& S# U7 Q' t  O6 S7 g
* Return nonzero if get value successfully */
1 x8 |( O/ g1 T% [8 Aint GetExpValue(_Tstream& istrin, _T& nReturn){
" r1 r6 s& e0 }3 J9 p: |    _T t[3] = {0}; //雨中飞燕之作# @: M. k* A8 x+ `
    char csym[3] = "++";
8 L# m6 F5 Y' }4 c+ I" Z  B    int nLevel = 1, nERR = 0;
: C2 Z9 B" T/ z0 H0 H    if(!(istrin>>t[1]))istrin.clear();
5 j' Z. x  V- T  e    for(;;){, g$ a5 C# _2 o3 r8 i
        if(istrin>>csym[2]){
" s" m* E- x: a4 P8 @, z            switch(csym[2]){
7 @4 \3 ]/ `# m) W; J$ \0 X: I            case '(':
, q. m4 t/ U6 Q! d1 ?7 @& g                if(!csym[1]){nLevel=0x100; nERR=1;}else+ T+ d; J) K+ F; f% }
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;& o( D. Z9 Z4 A9 G, J2 c! E) w5 w
                else{nLevel=0x100; nERR=1;}
) ~, d* |0 b& B0 y; K- e                break;. K0 p: q* g, k' Z
            case ')':/ f, a5 X; w% d) W$ k: m( D
                {nLevel = 0x100;}break;! b$ {  a1 D4 j
            case '+':case '-':case '*':case '/':8 ]6 n8 c' X4 L9 d$ y4 |$ w: s
                {csym[nLevel++] = csym[2];}break;  F* K# \+ Z# o( x! {
            case ' ':case '\r':case '\n':case '\t':continue;
8 w9 |; l0 T; E+ a4 `3 q9 n6 R4 ?            default:: K) `6 T( {1 B* f
                {nLevel=0x100; nERR=1;}
  Y: c9 y  _8 B6 L1 h* F0 B' i! _            }
. F9 U1 x9 c" O' w" u            if(nLevel==0x100)break;
! a1 J) y% Y9 L7 s" o1 E0 V& L            if(nLevel&0x10 || istrin>>t[2]){# i( }# j( K" |( e4 l" [
                nLevel &= 0xF;$ v) u6 X0 o0 S( x6 Z- s) q
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}3 Y% v  ~& d5 W6 a' c# @% f) }
                if(csym[1]=='*'||csym[1]=='/'){
, Q5 a& ?! L3 x2 P- A: }& Y0 J7 ^                    GetExpValue(t+1, csym[1]);
4 Y& N3 y' n: |1 C2 j" W                }% T0 K8 o, @) d# h
                else{
% P% Z% @0 q: D9 H3 T                    GetExpValue(t, csym[0]);, W  D8 @. w2 V7 v; _
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;6 E" _0 x1 T$ F3 o8 ?
                }
4 [+ _" y0 f  K5 h' t! L+ U4 |                nLevel = 1;
8 x# t% u3 d$ N            }
5 V/ m6 e+ D% Z: X; Y. G            else istrin.clear();! G1 N, X; K) K/ s; t/ p" M
        }$ X8 A. D/ G' i  g! ~3 E
        else{nERR = -1; break;}
3 e" @1 n2 H1 Z4 ?    }3 A! D! {4 g5 O) y# O! |
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);- p+ I: a2 L) \
    else nReturn=GetExpValue(t, csym[0]);
+ c* h& O; q- l    return nERR==-1?1:0;+ }/ w5 y5 f; U+ u1 a0 U1 `
}}
' _& ~* O5 v  v  a, O# I8 T! g
5 X5 V& ~# J' T/ o5 m  S, r6 W+ v
6 N' L7 L) _7 o/ T" s5 \; ?! b* ~% n* c; a- U) C, z! ~1 Z$ e
函数模板使用示例:
2 a. A/ e) G9 ~9 Y, S2 b5 C在以上那段代码的后面加上以下代码:+ s0 T* j1 k) R" A  b

/ t. b3 g+ V: C# X8 K* O , F" k- i  |+ p' R) u
: A7 Q' D) Q( v  z( S7 H- l% a
程序代码:
, }* ?7 J7 I7 a* p2 y6 ~4 ?9 y8 Y5 I# J! i3 v& m
#include<strstream>5 e, }5 y% z/ h# X( X0 k
#include<iostream>% R( E) e/ L  d5 _/ ~$ z
#include<string>
: [, y! m: c1 X2 H+ r# [2 `! ?using namespace std;
+ n5 U) v  n; p4 F0 U/ v$ ?  sint main(void)0 t/ [6 Y( \' Q/ d
{3 R, s) O/ m2 X) |' q' v1 z
    string s1;
( ~. ~1 ?, a% C7 T: r# `; V. J3 M    while(cin>>s1)
! s* {( v$ B! ~8 `2 p    {
) n* r6 {! |$ o0 Z7 |* J$ N6 B        istrstream isin(s1.data());
  ~3 p2 j9 A3 L5 a0 K        double d;# q7 v8 w( X- A
        if(fy_Exp::GetExpValue(isin, d))
, P* _  f+ n# r8 S0 ?+ C        {
4 i6 q2 C9 R' @( f            cout<<d<<endl;
0 g! w0 N. L; b' @        }
3 @! R) J$ s+ g& L+ O        else2 C# e/ {; j  ?4 f" N- d
        {7 D) I4 S+ [! s! D7 P8 C
            cout<<"ERROR"<<endl;5 S) @$ W1 g4 ~5 Y
        }) c( C) ]% b8 n3 j, ]% `5 b
    }" I( b& w. s8 d  L( p
    return 0;
/ R' r' h8 v/ C5 M# H# E}+ O$ z8 r3 L8 }6 |) i) \; p8 Y

1 n; i( _# Y) Z
) y: y: u$ F0 |4 H% N+ D, G然后编译执行就可以了(*^_^*)* I; Z8 t$ r: `  x+ w  p8 }9 e
其它:TC++上一定编译错误,不保证在VC6上也能通过编译9 C1 H' f' y) ~$ J% [; y8 A
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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