返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
2 Q0 j. G( D+ x6 z3 W一个很方便的函数模板,可以并且只可以计算含括号的四则表达式( |4 l2 v& L2 U$ _. b  \3 n
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
; A2 Q) [1 _# Y# m) t% v参数解释:4 I4 n6 s# \# k2 j3 f) `
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流9 h1 P9 b7 h* B. q6 C5 Z
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
# _, e! w6 ?  O8 c$ ~3 T+ ~返回值:6 w9 P  ]/ c  T; z) @, @6 n
返回非0表示计算成功,0表示计算失败有错误2 r$ O7 M  k6 w
& R- {( R  S9 m4 L7 @4 O

6 u, [: r1 J, W! s* ?4 C" _, h' F2 W3 V0 T6 k8 X: x
程序代码: 5 i( R4 `! X% \7 P* F/ R

* Z- I9 Y, Y5 B/ Wnamespace fy_Exp{$ J0 m, K: s8 g3 d& M4 l/ O
namespace {template <class _T>9 j. ^2 m, u* F, J" Y+ q
inline _T GetExpValue(_T t[], char& csym){2 X  R; m- ^4 W* `2 J5 j) ?" }
    char c=csym; csym=0;
/ z% a. h3 `: @2 j8 J2 t1 u& Z+ B    switch(c){
7 }/ j+ `' L+ j7 B    case '+':return t[0] += t[1];
* e& B( k& d8 T7 q- R5 z: y0 X    case '-':return t[0] -= t[1];
! Z. O% b) U6 U6 W* S# ^6 ]    case '*':return t[0] *= t[1];* I' e6 u% h. `, a& |, a/ ~9 s
    default: return t[0] /= t[1];//case '/':
9 x" l. `. }: o- {" _    }1 i' R) Y, t' T1 |
}}
+ J" ~- k0 L, B' A4 ptemplate <class _T, class _Tstream>
! C! w2 S- c+ ?2 {  \. {/* _Tstream: inputstream, _T: get return value( k2 W0 z4 Q# o* Z' e3 C
* Return nonzero if get value successfully */1 P; L& `9 z* j5 _$ B& D" U
int GetExpValue(_Tstream& istrin, _T& nReturn){
5 }8 L! H* l0 p    _T t[3] = {0}; //雨中飞燕之作6 {& ]( Z  V+ {$ @! u
    char csym[3] = "++";: M4 x- z2 {% {) _+ e
    int nLevel = 1, nERR = 0;
. `1 Q( ?# M6 b/ b$ i9 y# \    if(!(istrin>>t[1]))istrin.clear();
- K+ ]8 F' d' P/ B% E5 a8 ?; S6 [    for(;;){
6 m" A1 B$ X9 Z% }$ N. o        if(istrin>>csym[2]){5 ~( i6 U, h1 y$ }* W4 P
            switch(csym[2]){7 T( j% a( M  x3 c. e$ {- {, |
            case '(':
6 S1 x$ H( @% t                if(!csym[1]){nLevel=0x100; nERR=1;}else6 q1 B4 K- g  L' ~; ^5 O: {
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;$ k( ?0 O' H. c
                else{nLevel=0x100; nERR=1;}2 J$ t2 x' C  H  J! p) Y8 `
                break;  ]# \* ?0 C' r" J+ P$ ~4 B
            case ')':) u" `  z) r+ G4 l. t0 U# K4 ?6 O/ F
                {nLevel = 0x100;}break;$ ^2 S! p  Q4 S2 Z+ W  }7 H
            case '+':case '-':case '*':case '/':/ x  W3 \6 B/ U- B
                {csym[nLevel++] = csym[2];}break;2 O. z, ?  l" O2 i. U2 N0 d
            case ' ':case '\r':case '\n':case '\t':continue;7 D. F9 @; W$ y. l+ ^
            default:& Q( ~8 Z% a1 w" {3 k( q+ G
                {nLevel=0x100; nERR=1;}
8 v: B6 P- h& f0 {. T            }
# ~" R% K  X; o9 Q            if(nLevel==0x100)break;4 _& f# S( k% c/ k8 L. l+ M9 G8 J
            if(nLevel&0x10 || istrin>>t[2]){
; j1 C  f# @6 \                nLevel &= 0xF;
$ v8 z" D5 P: W) V; w. @                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}4 E! N: X+ E$ K- D
                if(csym[1]=='*'||csym[1]=='/'){
5 k  x$ M  G- A4 \                    GetExpValue(t+1, csym[1]);" r, S. \, _! p; V4 F! q
                }
0 Z$ A8 l  Z8 L. e                else{$ _) V. V$ _5 o8 p% I( s
                    GetExpValue(t, csym[0]);  P( q/ ^8 t4 T
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
8 t0 i& Z. a/ T6 x: a                }/ g/ r& b$ d5 ]' U! k7 q' h" h( T1 Q
                nLevel = 1;
! V5 ~/ Y8 o1 _+ E! u7 L            }8 C. L3 T2 t$ S1 |* B
            else istrin.clear();2 m0 v+ K- L* I/ H6 ?1 j
        }
  }. N0 r" }+ S- _* u7 m$ N9 i        else{nERR = -1; break;}1 K' q9 ~7 [& d/ ~' y7 t. w
    }0 I/ J- [; a: a9 z% R
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);" W9 |5 m) |. A
    else nReturn=GetExpValue(t, csym[0]);8 I- j' u9 h" R. O9 E% c5 {1 o
    return nERR==-1?1:0;
4 M$ L( d4 @: F. x}}( r  f/ T9 Z; i$ ?
& A9 s0 v- _4 V: K. `# j, h- Z

5 N! ~7 w2 C; s; c
) b' s) m& f& _) e函数模板使用示例:
  A) D# j( s3 n' ]在以上那段代码的后面加上以下代码:
& I4 W7 l4 N3 ^$ T6 [1 k9 O" V. }) i- t4 r4 x
1 z+ @8 i: Z/ @6 ]

6 T& G! ~1 t: m程序代码: & D: ]1 A- q# |& |. n! s
6 ?2 G% V7 \  q' Z5 K# \
#include<strstream>9 X% @5 I! Q% s" u4 j
#include<iostream>
7 B+ V4 Q4 }$ R$ s; W! W; z#include<string>
0 S# d: b/ A/ A3 h3 n* S$ {( L  m0 Jusing namespace std;8 S+ l3 E8 B* u/ X; H7 }( ]7 j
int main(void)
& S: ^$ a. c- x7 y) n{
% e! i" t' {" h3 }    string s1;9 X5 p" [  K$ o: s
    while(cin>>s1)1 ?3 I( }- y: W9 v/ Y5 J9 M
    {* ]0 g" i4 E8 ]* ^
        istrstream isin(s1.data());
$ u$ k7 V2 z. s" p" j/ X& p        double d;# Y) r- f% P* Q! m( K' h
        if(fy_Exp::GetExpValue(isin, d))
+ ^/ q4 p  K. S: j8 V0 p1 h        {
* ?) |7 \/ E5 f/ E            cout<<d<<endl;
$ u- n$ R  ?8 }5 A3 w! P* _        }
/ f4 T! X; {: o  l3 ]        else4 v$ Q8 k8 Z4 v/ R: _# E9 G
        {$ m* Z0 y/ H9 v% [0 K' C6 E
            cout<<"ERROR"<<endl;
2 x* {4 Z; C, O: o9 F$ F6 o        }8 V% I5 H5 y) J* l5 U5 W5 L
    }
; C3 M" d/ g- G0 u1 [( f    return 0;
" @2 l3 _5 K# e+ Y5 k' b}
% w5 `2 K/ e9 t
8 M" R+ D, w( [+ b
% ^, e7 W9 t* A8 e! x" x. }; g9 n, b% c然后编译执行就可以了(*^_^*)
7 A& ~& z) p4 z. O5 F其它:TC++上一定编译错误,不保证在VC6上也能通过编译
+ W0 G% a: X2 I% q, ?" g+ T      建议使用VC7或VC更高版本,或者使用GNU C++编译

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