返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,' ]# ?! O1 b: @. \8 d) R1 Y( \
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式) f7 y! a; L, h1 K
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)5 v/ ~  f" j2 Z/ Q+ n* V
参数解释:. ^4 f6 V( J1 C. |1 k
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流8 k- g/ `- O* l1 e8 y
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定' R7 O$ R) Z4 c: j: z: r
返回值:5 F5 i3 E6 B" s9 N
返回非0表示计算成功,0表示计算失败有错误. v+ z# N- s5 N3 P) n

9 ?0 o! F: C4 q0 x2 W( L& F9 p
1 l( D9 o7 E' F# K% p9 p/ h4 r
6 x$ D0 r: A( @* i. A6 N程序代码: ; f+ ~# o4 W$ D9 G% h, S$ }- }, j

0 W$ B1 ^0 I- C: f0 g# {% d. xnamespace fy_Exp{, Q8 ?+ M* R7 U, t7 Q
namespace {template <class _T>! }6 ?& @& n& G0 o
inline _T GetExpValue(_T t[], char& csym){
* ^3 n+ H/ ^  _( H0 j    char c=csym; csym=0;
6 a% r# R5 _8 u2 O% g. g  g$ e    switch(c){
- @( ~! O" a" }1 v3 r: r    case '+':return t[0] += t[1];1 j4 J$ P0 U  W8 ]* q8 _
    case '-':return t[0] -= t[1];
( Z3 R# I+ b  K5 l7 j9 {    case '*':return t[0] *= t[1];
; w: o3 |# [$ s( m1 w    default: return t[0] /= t[1];//case '/':- G( w. e# U9 z! W. H
    }. B; S3 B, t; e2 o. h
}}9 K! e# ^4 _% W2 h- M. D
template <class _T, class _Tstream>6 X( j# A& r9 P: p' p. K
/* _Tstream: inputstream, _T: get return value
+ w3 w3 q; c: u1 p" n9 p* Return nonzero if get value successfully */
) ^* r, U6 |! Cint GetExpValue(_Tstream& istrin, _T& nReturn){
: `2 C2 Z- l- r    _T t[3] = {0}; //雨中飞燕之作
* Z" J- ~" T5 Y! J    char csym[3] = "++";8 t: h9 ]& i9 V* M3 R
    int nLevel = 1, nERR = 0;* i' O, A8 y2 x0 O6 J. k; k
    if(!(istrin>>t[1]))istrin.clear();, w2 G6 C0 h8 x; ^2 X( P
    for(;;){
! d4 |9 u) r) u  y) T  |        if(istrin>>csym[2]){
9 P9 H( z9 g) p: Q- w, F9 q            switch(csym[2]){
/ _$ |7 H1 g1 N; J9 |            case '(':
! G% N* v  e" X# j, N7 S+ Z$ `' C/ @                if(!csym[1]){nLevel=0x100; nERR=1;}else! r, {7 z  P  r4 {7 {
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;, h& k7 O. q% O8 ~' z2 B- v# H1 {
                else{nLevel=0x100; nERR=1;}! }# h' s3 w) E0 W, T
                break;
6 _6 @4 K) `- w5 c" g            case ')':
9 r: Y1 ~8 g! H& A( f2 {- R                {nLevel = 0x100;}break;
; L& m1 }1 W- ?- {7 S            case '+':case '-':case '*':case '/':
' t" B: N- Q/ u& _$ _$ [$ W$ g7 f                {csym[nLevel++] = csym[2];}break;
& x" d. e- i/ p/ d6 p            case ' ':case '\r':case '\n':case '\t':continue;" ]3 C, }+ G' I7 A
            default:
5 ^+ [9 E+ t: ~; g/ |. s0 K7 S* O0 c% m' t                {nLevel=0x100; nERR=1;}
; D0 v+ ~+ J9 ]- ~9 `            }' t' E+ e" x) E* n
            if(nLevel==0x100)break;& f6 P5 ~  u& V7 x2 s$ T$ }
            if(nLevel&0x10 || istrin>>t[2]){0 e$ `; n$ }1 N* a7 t/ V
                nLevel &= 0xF;
$ j9 [% c; t' M5 _                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
- t' p7 \. S2 E, h                if(csym[1]=='*'||csym[1]=='/'){
( j- \$ L0 @# Y3 T2 z% F# {                    GetExpValue(t+1, csym[1]);; d2 ?! u! n% \, ?+ T
                }
. Q2 m# T$ [- }  u- g) v- [1 R# @                else{: }6 I, d$ o3 P5 X, Z, N
                    GetExpValue(t, csym[0]);
* p1 \; Q7 E, j% d7 P3 A                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;+ \/ ^6 X- u& n  |
                }( J/ q8 R# }1 _8 C
                nLevel = 1;: k8 o/ {* ]* q7 K: R
            }7 V! B( U- ~) m+ W+ d, m* r
            else istrin.clear();
  ~: G  `$ ^7 b* G+ m, R$ e6 t        }6 ~$ W/ v1 ~' b7 F
        else{nERR = -1; break;}
; H8 R# ~6 s  r2 @7 W    }- |/ ?, J0 T" g3 X
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);5 I% @' M3 L* z0 \. T% }1 y
    else nReturn=GetExpValue(t, csym[0]);
3 O& X: w' S+ Q$ \9 {7 }0 n    return nERR==-1?1:0;9 w* B' k* ^; G' L) w& p2 Y
}}6 n) S5 j1 X8 G0 O) I. ~' n
6 u2 ]) Z. n8 F$ M; `' s
" n) ~5 K4 K' O' R

# j( a" ?2 x: i: I- y: K函数模板使用示例:
  b; Z( J& Y* W# @3 Z在以上那段代码的后面加上以下代码:
. `1 p7 W) g8 J1 J& H  D% O' `- S% @* f; h9 _8 y, }9 ]

0 }5 t1 O2 Y1 L7 g4 q, l2 H. g
7 n- F2 l) \! z. {8 o程序代码: ' B7 C( z( C9 K1 Z
+ F$ B+ k5 I( f; Q
#include<strstream>
/ M' x1 M6 S' c#include<iostream>
6 y4 F) ~5 F( t1 i  S& u5 @- S5 a#include<string>5 e- C, r  P# d+ g5 Y7 Z
using namespace std;3 j; C/ @6 p7 g3 E
int main(void)
! I" _0 d; l4 \3 q) }3 n: c- f{
9 ?( Q1 n# n0 K! @7 e    string s1;) o- ~3 d7 i1 K/ Q. ^! j7 E& K
    while(cin>>s1)
0 p5 V6 |  l  V3 s$ c" x) \    {$ x  c+ e: Q+ N
        istrstream isin(s1.data());/ H2 v4 K* g2 \) X
        double d;
0 j$ Q7 e4 R7 [6 b& R6 I; |        if(fy_Exp::GetExpValue(isin, d))! R% |8 p  {' i2 b- k' D
        {
' }% l% Z* R& P            cout<<d<<endl;
, v$ h* j- ~5 w' {: g, K; @        }
7 i5 h* ^2 G# U! v$ a7 g/ _        else
/ \+ h! \- f  v5 X7 j        {
6 E# g7 S) l; U6 l$ z            cout<<"ERROR"<<endl;' G0 X: E( ]  q: x6 D5 i
        }. q, P6 q! V. |) v: y( a
    }
8 ~+ B3 ]4 x) L8 `8 c$ T& e% g    return 0;; p* P1 c) g+ H1 v
}2 g; ~$ S! j2 }. A
" W: D6 \/ P* b! i, V3 T- ~
4 W/ |1 r- i1 O5 _
然后编译执行就可以了(*^_^*)& L- B( ?- U8 e2 l+ w  O% i& M
其它:TC++上一定编译错误,不保证在VC6上也能通过编译
" w! E. s, a7 E% A      建议使用VC7或VC更高版本,或者使用GNU C++编译

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