返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,8 [' D# A) E2 s$ g+ |" L  k
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
* b/ ?( F5 Y  g只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
/ ~) j& B4 l7 x" `参数解释:. Y2 s( a: R0 c, f2 H
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
# p, q/ y! U" n' _nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定$ L- W, ^& {5 z+ t0 I
返回值:
9 D4 P% w8 U+ e. U/ |9 ^返回非0表示计算成功,0表示计算失败有错误
' T$ A1 `, c; U5 b8 Y2 y
9 X2 p, }# j4 Y( L9 O% y: f- f
/ \0 X' t/ c' G- g* G: K) o; d. k! w+ i. u- H
程序代码: ( G" ?$ S" X. z, u; ?
) C: ?* I6 o% M0 l1 o) I7 }$ N/ V
namespace fy_Exp{
0 D' @5 ~$ r- K4 J7 B/ Bnamespace {template <class _T>+ }" ~7 K  S4 O
inline _T GetExpValue(_T t[], char& csym){+ w* p1 M, ~5 _7 m8 m
    char c=csym; csym=0;  ]3 z4 w" n* b' ]7 u9 ?, R
    switch(c){
  @  D3 R! B% C( a8 b, l    case '+':return t[0] += t[1];4 O2 U. K; F( S: ~: S- H6 S2 R
    case '-':return t[0] -= t[1];/ m4 C4 P; y4 ]
    case '*':return t[0] *= t[1];/ ~, }0 T/ z8 C! N  V5 s
    default: return t[0] /= t[1];//case '/':: O1 @9 }7 g2 L& z0 d
    }8 m' R1 f/ ^0 p* x5 T8 N
}}" |' @2 ^) d6 T, P3 U9 t; q) n% V
template <class _T, class _Tstream>
5 a9 U3 ]" u7 @3 V7 K) J: Y" i, V/* _Tstream: inputstream, _T: get return value1 ?) ?1 E) v; Q0 O1 _
* Return nonzero if get value successfully */
' q# p4 S5 I, J( s# j- i  Q9 I7 j4 [int GetExpValue(_Tstream& istrin, _T& nReturn){
# r: E" k2 F7 g, F% O$ v8 u2 K/ _    _T t[3] = {0}; //雨中飞燕之作0 S; Q& C! U) e8 F. N; o) e
    char csym[3] = "++";& z3 E# D+ w. Z; E- e; y
    int nLevel = 1, nERR = 0;, f" M" W& B. \/ U
    if(!(istrin>>t[1]))istrin.clear();
; o6 F! [, x8 S    for(;;){: u7 |* X$ `( b- C' _" P
        if(istrin>>csym[2]){
! ?' c7 e  r$ n! ]8 c* x4 i            switch(csym[2]){
. @6 w7 w) p; `. Y. J            case '(':
. `3 E" b4 V$ p* _; C                if(!csym[1]){nLevel=0x100; nERR=1;}else
+ Q2 M4 z  g8 J2 a( o! Q& o; a                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
5 e" r0 W3 t$ j5 N3 d; W) k8 z* ^                else{nLevel=0x100; nERR=1;}+ P/ W7 n$ @) x# e% w
                break;+ z! R+ c# g- _2 T  ~. z7 s4 w
            case ')':
$ ~2 {; z- \0 J0 `9 K+ r6 l                {nLevel = 0x100;}break;
! F- ^" `5 }( D6 n" j            case '+':case '-':case '*':case '/':/ G& N6 s: X) g0 k
                {csym[nLevel++] = csym[2];}break;# G! I. R; t! i. n/ F- u) Z7 v* k2 T( f
            case ' ':case '\r':case '\n':case '\t':continue;
; T8 |8 G2 R$ o# P$ G6 `9 a7 \- y            default:
3 @: K) l0 y) g- L% c                {nLevel=0x100; nERR=1;}
4 P* Y8 f' c* |3 g            }
3 F( P" `9 H4 _9 u5 C0 A            if(nLevel==0x100)break;  a) h$ T, `7 R. S
            if(nLevel&0x10 || istrin>>t[2]){
) q3 a9 G( Z$ m: L4 d2 L                nLevel &= 0xF;$ l' l9 G' ]7 }5 A( I
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
8 J+ V" j: p! c  Y5 _4 K& _3 S  ^4 T                if(csym[1]=='*'||csym[1]=='/'){
6 d8 p, S. W7 g5 m7 e- E* p                    GetExpValue(t+1, csym[1]);; l. p& u: b: t0 i4 n( W
                }
+ k- P8 M: Y1 l- P% {* L# V0 J                else{  n4 d, _* n: Q8 i" T, N$ b
                    GetExpValue(t, csym[0]);
# c- \) q1 d, [) x4 Z                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;# s. |% ^) g/ \0 l
                }
! m; [# ]- r0 e4 w                nLevel = 1;4 [# g+ v3 l3 B& @/ N
            }, W8 I; S6 `9 }3 a% [* T
            else istrin.clear();
. P& ]) f2 ]' [        }# `6 c7 m- O  f4 d
        else{nERR = -1; break;}
* ]( X2 s2 h$ Z8 n+ j& @8 a    }( e% L0 k2 C" D' ~3 T% u" \
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
  a+ K# g/ y# V7 w    else nReturn=GetExpValue(t, csym[0]);
0 B# V6 i* ^( d( @7 u0 ]    return nERR==-1?1:0;) E$ X9 h" v, O" d. E" e
}}& U! V/ l( F. j- T6 V

- o& ]  ~8 o2 R7 w. O: ?# i+ {- u9 s
8 K. X& v# ]8 A" P: [  M. E4 u8 k& t6 d) r6 u
函数模板使用示例:+ z$ q4 j5 k1 G' v0 {1 f! X
在以上那段代码的后面加上以下代码:
/ P6 T2 ]1 S1 ]! [. q9 G1 l5 n( e3 l8 A' S8 w- i) l

9 e' a: K, u2 N1 G- f
1 H' G1 B* ~  j9 T1 X" }4 ~5 n程序代码:
0 `) N% C2 Z8 o! s, Y/ ^
. D8 H% B- w+ V5 Y* u  s#include<strstream>  z6 V( @' V3 {
#include<iostream>
; F  x# N1 ]2 d; R& p, S#include<string>
; H, L7 }) O. ]& Z8 busing namespace std;) m' |) j* l! J/ D1 |: E
int main(void)
6 {+ E9 m6 N/ w" P{
* E: I# z( ]) o3 U  v    string s1;8 X& w6 w- ^! @% e
    while(cin>>s1)
# ^8 [0 y/ [2 s/ W! X    {
7 i+ N5 M$ Z/ q% t& G        istrstream isin(s1.data());9 `4 ^" b" j+ ?8 c0 g" x; B
        double d;& V" k. k; Y" k
        if(fy_Exp::GetExpValue(isin, d))
& g5 @$ |' S, g        {  Z5 b3 a, H- j0 o8 ~% ]1 J
            cout<<d<<endl;6 @( L7 L" W$ S) L4 k
        }
, E- c$ |% m7 d* }2 d/ d        else
+ E; s2 q3 T3 ^; ?  L4 K4 `) [, s        {
- X; [- M8 v3 J1 ]; ]: V& M) x& K2 T            cout<<"ERROR"<<endl;2 G, E. e9 i+ A$ ^% K! f# J) O
        }
( n" y6 e+ i  S; U    }; \( G9 e: Y4 x7 q: L! e7 O
    return 0;$ `) b  v/ L6 t
}
- ^0 V% P% r. x8 O3 W  ]. ?( Q( N4 R2 p3 Z8 R; V8 J
# L5 M5 j% v) v, O0 _$ ^5 \# g
然后编译执行就可以了(*^_^*)) c( Z6 a9 @! f: O" R; G/ G
其它:TC++上一定编译错误,不保证在VC6上也能通过编译
# Y! Q9 g% y' e+ H$ ~6 V      建议使用VC7或VC更高版本,或者使用GNU C++编译

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