返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,) C! m; m" U; p( F7 ~! Y/ J
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式6 n! s9 E4 v% z4 u3 e
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
: k" E- W% M9 m' y. @参数解释:
, _: ?: f& h* n/ H9 Histrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
9 ]% j: Y6 }6 M8 f3 VnReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
% B$ k* m" z# [返回值:
/ {; P( q9 @8 K- M返回非0表示计算成功,0表示计算失败有错误
. O& }6 }& G  o! K3 h) g: F4 c7 c2 x( ?0 R* Y2 j) W) |- m+ ?( O
( E7 z* p8 X- ?+ o
( d  Y1 Y8 r9 _- O: o9 v& b" V9 s
程序代码:
0 H1 e$ L% a* O9 s# m) b$ v
2 F4 }8 u6 W5 v# A; C- y) K5 xnamespace fy_Exp{  s4 {, K+ L. Z& {& n* H+ M; G
namespace {template <class _T>
: D% x" ?' `3 p+ Minline _T GetExpValue(_T t[], char& csym){
  D; `7 m0 V) Z8 [( D5 w5 Y" o    char c=csym; csym=0;
/ Q# ^# m0 H+ C* E3 L- c* I    switch(c){9 s! j* l- i  q
    case '+':return t[0] += t[1];5 u( E) }, x2 ]" M' }6 l# Y$ X) ~
    case '-':return t[0] -= t[1];
0 s' x/ P2 ?2 z5 r    case '*':return t[0] *= t[1];2 m& w, Q9 d! L
    default: return t[0] /= t[1];//case '/':
( M( i$ E0 z- Y6 \/ y7 [    }
+ \) \& M* p' \}}
$ b" O9 \* S' E6 s/ ptemplate <class _T, class _Tstream>
% A* I7 D; h: F/* _Tstream: inputstream, _T: get return value
) v7 a) d' G, b  t6 V* Return nonzero if get value successfully */
/ Q1 f' T" I9 ^int GetExpValue(_Tstream& istrin, _T& nReturn){
8 v( w3 g" C. T+ h) Q" p    _T t[3] = {0}; //雨中飞燕之作
" L0 j, h2 r# x" I- p    char csym[3] = "++";5 l8 Z+ S+ W4 i/ `& f; r$ {+ {7 x
    int nLevel = 1, nERR = 0;
: T8 ^' t8 u; @( z9 ?' Y    if(!(istrin>>t[1]))istrin.clear();
$ P1 \0 T. C' \8 s& A; j" m    for(;;){
% n( x: v5 g1 @, g! d( L5 e        if(istrin>>csym[2]){4 x! U( [: H& v% I2 D9 d+ K+ K) z
            switch(csym[2]){, n: Y* h( X" R* D
            case '(':, ~2 c. e& d# ]& g; r: N' s" O
                if(!csym[1]){nLevel=0x100; nERR=1;}else& V  B8 W% z6 z& o% n0 p% ~  J. }
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;' U+ x3 P+ m% h( V/ k& K- R
                else{nLevel=0x100; nERR=1;}9 u* R5 O% x. c  z1 o
                break;
6 }' \8 I; h4 T5 T6 V" `4 M3 n            case ')':
3 h! T5 {! h/ C                {nLevel = 0x100;}break;7 p& Q* q% i6 I9 p
            case '+':case '-':case '*':case '/':
% t; U- O/ k( ~# @* ?                {csym[nLevel++] = csym[2];}break;
4 Y9 ^) t4 h6 w: G* C' x. z- J+ ]            case ' ':case '\r':case '\n':case '\t':continue;5 `' S% b; j# S' X+ a
            default:2 B3 H, \4 ^; u: L1 ^
                {nLevel=0x100; nERR=1;}* J1 T4 H; o7 `  N% t
            }; U  ^: T: A$ X+ J/ p1 s
            if(nLevel==0x100)break;7 X& B) u: m5 ?# c5 t9 A
            if(nLevel&0x10 || istrin>>t[2]){
4 [+ L* p0 V1 [                nLevel &= 0xF;( i4 n/ |, ~) ]8 g2 Y# ?' U
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}+ }% Y! k5 W+ E7 R9 w  K
                if(csym[1]=='*'||csym[1]=='/'){
! x3 x7 }. P+ v4 W/ `" g/ G2 o' D                    GetExpValue(t+1, csym[1]);
; H: P+ d  \5 J$ Z% I) f7 O5 B" r                }
& H* y1 M/ \% X; b2 B4 S9 T4 L                else{
# P8 |( O/ l9 i- ^' t2 s                    GetExpValue(t, csym[0]);9 }4 j6 N1 ~# Y; ?
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;8 P: U1 k8 f$ M: a; P; ?
                }" |( k7 F/ S8 l# f7 ?: s) O& u
                nLevel = 1;+ Y& w3 c8 A+ h, H/ \, m
            }. _( u- p; \- M4 D
            else istrin.clear();! x- b, \: k' |5 C# q9 C
        }
( K4 c6 y0 n5 x        else{nERR = -1; break;}
  I- c& M- ?& t9 {1 m5 j7 Y    }
6 C$ n& j; Z6 z5 E: T5 }    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);% C4 b: `  c" u4 o; [- a( \
    else nReturn=GetExpValue(t, csym[0]);
* q8 G! {3 ^. ?+ B" m' a    return nERR==-1?1:0;
  B, N& t) @6 J* d6 ^/ B}}
/ q/ E" s' o. ?0 R' K
$ B( a8 @5 l1 r4 S3 y3 g
) E+ b$ {6 c+ b3 @
9 y) b) E, s+ E函数模板使用示例:' r3 j1 H- N; i4 n, h
在以上那段代码的后面加上以下代码:7 K9 `" Z$ |( Q0 Z- U! _' U

  ]& Z2 D+ u2 c/ U
: M% p& e( [4 ?4 t0 |% p1 S- M1 }8 f; \/ j1 E
程序代码: % m& n1 h$ O! ~  E
" S: F# j1 Q0 g& ], G
#include<strstream>
0 r/ r4 P; A5 t9 h3 O2 {! H#include<iostream>; O* [/ f) t  A
#include<string>
1 ~$ i& X& a1 H% tusing namespace std;
5 X. ?$ t+ C3 i3 o/ dint main(void), T6 ^$ i: C  t2 L& Z) [4 H
{
! j: S) a! U% N( P* T5 }% t    string s1;
/ J$ h- f( n" A6 K% N! K2 U' B    while(cin>>s1)
2 w4 ?0 M. K6 D8 H    {
, o/ o9 r/ v, o. ^. p        istrstream isin(s1.data());& M4 p( v1 z6 i+ T9 z& n, e& s
        double d;( D5 U3 ^/ `9 G  u: {
        if(fy_Exp::GetExpValue(isin, d))7 {  R' f6 R( E( o0 ^* N
        {# V, F. T1 j8 k+ x
            cout<<d<<endl;
- T, O; [/ _  Z7 m7 B; R0 x        }- J& a+ I8 A6 V: U  j3 A# E) {! u
        else
) j! ~- I6 x; [5 K- I        {
* n5 ]1 [4 G9 l/ M            cout<<"ERROR"<<endl;3 X4 k  H' o& h) ^0 E7 k9 n8 E/ r/ y
        }" z# a( h; z9 A$ m
    }' Y- p% I7 d* y9 S6 R/ E' _7 I% m
    return 0;5 @3 _1 v- c; R8 F
}
% s1 ]4 ]6 J6 \
& G6 N6 \8 q7 X. R7 g, G* l5 b' H
$ l2 b: K% ]; A然后编译执行就可以了(*^_^*)# @$ E8 R5 j; g) S
其它:TC++上一定编译错误,不保证在VC6上也能通过编译
6 E$ G" O" p% {& Z4 k      建议使用VC7或VC更高版本,或者使用GNU C++编译

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