返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,- ?' A. J6 H8 m: \- Y
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式4 Z$ @: T- t1 ]4 z
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)+ u1 O, F* a: a: A1 N
参数解释:+ [0 k7 @* O9 Z8 ?9 c+ V
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
9 v2 ^$ H- J4 N8 Z) W) K4 D3 C3 ?" D) `nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
6 i/ B2 u; c9 e3 c: Y2 F6 I3 g返回值:  A& P+ B' ^: B' w
返回非0表示计算成功,0表示计算失败有错误- f8 M' f/ W) o8 O7 ]
$ j9 z; X! \9 l  _' u
* C/ i; M% h: ^. q/ Q1 n
! k$ s7 [- w3 ?* t. w
程序代码:
5 h8 `. q/ N! Z2 {7 \
# R( f4 \# U6 g0 o/ n3 V8 S8 G4 Mnamespace fy_Exp{
2 J. s0 G3 _+ |+ ~; M3 L2 S$ Anamespace {template <class _T>
' p# Y. f5 q4 X$ n/ t5 x, ^inline _T GetExpValue(_T t[], char& csym){" V9 {/ Z1 G, A3 Y2 G( o
    char c=csym; csym=0;
& K$ Y2 k2 t/ d5 p4 ~$ a2 u0 k% s    switch(c){
; N% ^' ^9 v2 }/ u  \; S    case '+':return t[0] += t[1];+ p. V. e( `0 x6 j
    case '-':return t[0] -= t[1];
. r$ J) _8 n+ y0 u/ Z" g% J    case '*':return t[0] *= t[1];: }$ C8 n) h; W8 x# G! O
    default: return t[0] /= t[1];//case '/':* e! p7 e. ~# p3 `
    }0 W7 p, D. l1 Q. A( L
}}
( s% x& }1 o3 [5 C6 F8 L6 Mtemplate <class _T, class _Tstream>. Q) x' q" l5 m2 r% j
/* _Tstream: inputstream, _T: get return value" z: r" N9 F% @" J- E' G; O- ~
* Return nonzero if get value successfully */7 \' G( K, C0 h) n) _  i0 ^0 Q5 Y9 m
int GetExpValue(_Tstream& istrin, _T& nReturn){
+ I; x9 K; k) Z# s" I    _T t[3] = {0}; //雨中飞燕之作
+ B0 F" K, G1 H. W    char csym[3] = "++";
. w4 J4 M$ _% U7 z    int nLevel = 1, nERR = 0;; P/ [# i# x8 t. o( Y
    if(!(istrin>>t[1]))istrin.clear();
! U* u2 k0 r2 b) E1 G7 |0 l    for(;;){( K3 v' V! |% ~. @' o6 ~
        if(istrin>>csym[2]){
' h  t9 O3 p% ~            switch(csym[2]){
* Y; `" i7 }) x" t) [0 c            case '(':1 ]6 ^5 D+ O( L. g# L9 {! L
                if(!csym[1]){nLevel=0x100; nERR=1;}else
( Q& J* H  F" D% ^3 S& o                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;/ S2 O! r+ }1 B) E4 a$ y  {' l
                else{nLevel=0x100; nERR=1;}
/ y1 x' F0 M2 g0 o( {                break;: m& L  u& m; o: R, Z8 Y
            case ')':
' V1 X  V! L/ s0 Z7 C                {nLevel = 0x100;}break;. q0 @0 K3 ^: {
            case '+':case '-':case '*':case '/':
5 @) p' l' q0 s% h                {csym[nLevel++] = csym[2];}break;# r" D" z0 a3 F( m4 G4 h$ B
            case ' ':case '\r':case '\n':case '\t':continue;
, [6 |$ \9 S) ^; I: R# {            default:
" f$ m4 S/ v$ }$ y+ P                {nLevel=0x100; nERR=1;}
) E) ~8 a7 _' m% k0 O6 D/ h            }- s2 u" }# ^; w% ]: S" u" u4 _" h0 z( @: ?
            if(nLevel==0x100)break;$ n+ a8 p) N! Z$ E, h" Y- e
            if(nLevel&0x10 || istrin>>t[2]){
3 g; O, k0 N4 C# G                nLevel &= 0xF;. q8 U9 }6 o/ }3 }# s* L  }# J& r
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
# ^& A; {- [6 `/ m; u                if(csym[1]=='*'||csym[1]=='/'){
- t/ _0 D& q* _' K) q9 [- u. w3 W6 A                    GetExpValue(t+1, csym[1]);8 O1 k' y$ m( M8 x" L
                }2 C; g$ O1 f1 }/ W3 E
                else{
0 z2 F! R* o1 O% c4 c5 o2 Q                    GetExpValue(t, csym[0]);  f0 @" `% l: ]. f5 U8 {
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
' f* n3 g/ A5 r" o/ X* H- C" k  k" z                }
/ V% G$ l8 ~+ _* k( b$ U6 a                nLevel = 1;; \: j0 N6 F0 _5 g: G
            }* _. q8 F0 p0 @% M3 n
            else istrin.clear();
: v0 @5 E" k, w  j$ D; ]2 Y        }
% E5 N# V  {! J        else{nERR = -1; break;}+ S% U: C7 `+ }
    }
) \. ]# G. w0 k4 h5 K6 {! x    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);4 N( L* q3 Q0 f
    else nReturn=GetExpValue(t, csym[0]);
5 ?6 p& M8 k+ @) v2 j# i    return nERR==-1?1:0;& Z; Q4 f+ W( N+ L( X( ]0 r# t
}}
  I* Y/ B' d- l4 j* N7 h  \0 D! w* Y+ K6 I, `" g2 n9 q) ]

3 ~) L6 ~: R) _' @" r
- t" |" V# r5 T3 h# G函数模板使用示例:
( D9 M7 t( J) W) S. ^! l$ j3 T在以上那段代码的后面加上以下代码:) N# l* t5 y; Q

8 T* e1 \+ P! |/ v- B+ C( M . a0 j1 q! |6 M7 [  u$ q( Z- R

  x% E2 ]; F  L9 j3 K7 u$ O5 g程序代码:
) P, ]% D& X  L: u3 Z- z  I; Y7 Q( k
#include<strstream>( q! L3 ?+ a5 s. ?6 O1 [, ^8 f
#include<iostream>
4 R+ G3 u" |: a# I: d/ `#include<string>7 @! g. z3 U9 ^5 @
using namespace std;; X  C6 O1 N# N. Z" ~2 {
int main(void)
- K3 |+ P* P- p5 h9 b{
7 a" \# s1 G, t( p' H    string s1;
& i* f& p! J0 c! n( N; T    while(cin>>s1)
  b+ J; F9 }( P6 ?# s    {
; g. c' a. I) y9 C4 o$ p        istrstream isin(s1.data());
5 i6 \( S8 M) U        double d;4 Y9 D( r. t. N8 H: h0 z$ p
        if(fy_Exp::GetExpValue(isin, d))% E9 ?( f+ b  e7 x4 B
        {
. u+ \" S& [! }+ f0 |9 I/ W' l            cout<<d<<endl;
/ @" V7 a9 B3 U# m3 j        }
5 r- M/ B& Y. p$ d        else
, E, v4 z$ @* E9 Q/ g; Z- n, u        {5 t/ ?" i% m7 B
            cout<<"ERROR"<<endl;
0 d3 O9 n3 P; {1 [! |/ z: {        }7 _. X: a. h3 T
    }
% l* A9 }6 y) h4 |7 g    return 0;
. f3 J( m' `- I2 [! {# L}1 L! ]& g( E6 d# q9 t- L% V2 m
4 P+ I% x+ D0 g. r0 P- Y7 F: u
9 C7 ^1 @+ O2 D% Z) U/ h
然后编译执行就可以了(*^_^*)7 R& \3 F* E2 h* S- L0 M4 h% k
其它:TC++上一定编译错误,不保证在VC6上也能通过编译
) n1 D7 F& s+ L) C8 f! a$ I      建议使用VC7或VC更高版本,或者使用GNU C++编译

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