返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
, x& `6 x2 k2 N9 M, C一个很方便的函数模板,可以并且只可以计算含括号的四则表达式6 }0 N* y/ Z+ w" h/ E$ E# i( p
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)6 S% A1 l$ M5 t+ l9 J. H" }4 a
参数解释:
) \: ]% b1 B* Y, @1 `istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流$ I3 ]& L3 I: J% ]7 P6 }
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
' K' J% }0 L  _9 W1 i返回值:5 S; n7 ]3 N% R$ [
返回非0表示计算成功,0表示计算失败有错误
  g: s  _: P. ?) w# L) q" T4 f9 \% h) B7 Q7 y: Z; s5 ~+ @
, l+ g- P: s. j+ F

4 _$ X, r4 {' E* [! ?程序代码:
) X3 J# \; l9 |! o7 H
) o2 Q* V" U; n! Gnamespace fy_Exp{( P$ w; K- {/ ~/ Z3 s# N" V' ]
namespace {template <class _T>* g4 V! i% V7 S( X" E& s5 K
inline _T GetExpValue(_T t[], char& csym){
$ ~! M/ s  }9 g/ W  ^    char c=csym; csym=0;# F) p- M( r; Y) H3 C* Y" |& q. V
    switch(c){
9 M1 ]+ ?& L. c6 q3 J    case '+':return t[0] += t[1];
+ M0 t0 \  o2 K; o% e    case '-':return t[0] -= t[1];
4 p5 \) V0 `" ?4 `! ?! m3 s" X    case '*':return t[0] *= t[1];( K. ^, V' ?; O% L, D8 G
    default: return t[0] /= t[1];//case '/':$ V4 |5 C7 b3 Z6 a* O2 i( Z
    }
: F/ M2 o  j/ J% U, E( H}}
7 Y5 \' f  N# Z" e. Ytemplate <class _T, class _Tstream>
7 m6 }7 ~' a/ Y/* _Tstream: inputstream, _T: get return value
7 l  I8 v: x5 s9 \* Return nonzero if get value successfully */  F' U  Y( m. Q+ L7 B8 d
int GetExpValue(_Tstream& istrin, _T& nReturn){7 T" f, e' Y; m
    _T t[3] = {0}; //雨中飞燕之作6 ]# A& p* ^( v, F& R2 O  V% [
    char csym[3] = "++";
3 \. ?7 q" m! z0 r! y. |" r    int nLevel = 1, nERR = 0;
, r* x% Y- f9 O    if(!(istrin>>t[1]))istrin.clear();
# {0 Y; @6 y$ h$ X/ Q( f1 f) Y    for(;;){; \  p( T4 _  X" B
        if(istrin>>csym[2]){0 f2 X4 E3 Z; @  s, ~" z
            switch(csym[2]){
* s  r0 n1 s! |( \, t* e5 _            case '(':0 d9 N! T! C3 r9 [0 g
                if(!csym[1]){nLevel=0x100; nERR=1;}else
- Q; T( J/ I3 w. ~                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
# {/ n( w% Y6 V* C3 ]; @) q- l                else{nLevel=0x100; nERR=1;}9 r+ q7 i6 D# W) G( S
                break;, p. X, ^+ T0 [7 a0 {& K
            case ')':% P- s$ j* Q: [9 U2 e/ U
                {nLevel = 0x100;}break;( ]( o8 T  i/ V0 \- a# V# q2 P
            case '+':case '-':case '*':case '/':7 I: c5 \$ @- d
                {csym[nLevel++] = csym[2];}break;
: D, U# |& u4 L' g9 c; [) \! c            case ' ':case '\r':case '\n':case '\t':continue;
: e- q& v! n" \+ A7 e            default:0 ?- `6 u. N  |: s! O/ g+ }
                {nLevel=0x100; nERR=1;}+ Y2 b; F; j: @; d
            }# i9 t: o8 E4 `
            if(nLevel==0x100)break;
# N4 F; U9 L; P            if(nLevel&0x10 || istrin>>t[2]){
$ Q+ O- T. z6 Q) W# d# r2 Q/ U1 ~                nLevel &= 0xF;) @3 k4 R  s+ ]  h. F
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
3 P# D0 J8 ^2 L! y7 F                if(csym[1]=='*'||csym[1]=='/'){
9 c% s# Y" w" K: V* Z3 L5 W  l                    GetExpValue(t+1, csym[1]);& t. x( h( k! j7 X0 \- f
                }
2 I% I4 ~" j, R3 d                else{
* M6 X+ Y  r2 f                    GetExpValue(t, csym[0]);- Y" f& g  Z1 d7 d: I" G2 |6 u+ c
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;* A* Z6 c4 F. \' f6 n( @! z5 h7 G
                }+ X7 X+ h2 Z& s6 K) ]9 Y7 W
                nLevel = 1;
$ ^/ n% ^* e$ K% k# p            }
! `+ \0 L0 E& l8 X. l9 y$ ~) D0 [            else istrin.clear();
8 L! n, Y+ N* |4 g        }) q/ E- {. Z) O* F" O
        else{nERR = -1; break;}0 o; p3 Q. z* r- C6 ~8 i1 U
    }! W3 m+ y- Q/ O# ]' k
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
. d" {/ ^( h" _' U    else nReturn=GetExpValue(t, csym[0]);$ R8 L) X$ d% U+ |9 d8 ?: H
    return nERR==-1?1:0;
6 D' g/ C6 q* E1 m* v4 P}}' Y. d& F6 @9 p7 R; j

* j, R6 u& ]  x0 \
4 x2 P( C( q1 x+ @) \" R; p# Q1 ^' `2 l( O$ F. @5 n
函数模板使用示例:' T: N9 v) v1 O( |+ ]
在以上那段代码的后面加上以下代码:/ c. e7 U# \# R

1 k# W' c- J  U& q' ^" T& g
, g2 s3 E. z/ k- Z
- r5 x2 E: {5 O  k- }程序代码:
; d: a% o8 x9 @/ z& H, c. g9 i5 O2 H/ V5 S( K! }
#include<strstream>6 f6 \: V; X) K! A; S# Z
#include<iostream>! }  o9 T3 N& q, P
#include<string>
' V9 h& h9 M- h$ n* g) Lusing namespace std;+ Z8 l& V: W& N+ Y# q* v" J" s) m3 |
int main(void)
; T6 p0 c/ i, K1 V; d{5 x% B" ]7 G$ k" ^3 R
    string s1;- I! J! _7 X& E; r
    while(cin>>s1)
) _+ @( O9 ^/ o, ^    {
0 H+ \+ q" m. s6 ]+ |0 v. W        istrstream isin(s1.data());% q) B7 |7 |/ o
        double d;$ y/ {6 s5 n/ ?/ U0 i7 U. F
        if(fy_Exp::GetExpValue(isin, d))2 s: u$ l0 A8 p( T+ @
        {
% g$ I8 O" k* e0 w$ D. ~            cout<<d<<endl;
; ]8 w" U0 R8 v! @+ E        }+ [' N) n0 J" a- k( u
        else. i6 p2 z6 r/ C% |: X8 I3 r' |
        {, m7 G. w2 w# b: Z2 t" S
            cout<<"ERROR"<<endl;; j  f4 `. u! _6 w4 h. ?; ^
        }
) V6 K; _& l% I    }
+ q1 |$ M, j5 a# K& h    return 0;
+ R* G( P4 r4 ]4 {}
0 L0 x- f  w; T, @
& x* C0 p9 u  W# z  Z! F/ \2 }$ y4 [9 U' c1 m# ?& O9 |
然后编译执行就可以了(*^_^*)
$ s& f8 |+ `1 I. p4 h其它:TC++上一定编译错误,不保证在VC6上也能通过编译
3 D1 o, V6 I# r! C7 b      建议使用VC7或VC更高版本,或者使用GNU C++编译

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