返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,5 V" [/ Y) Y5 J; h
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式/ }6 f# b# ]) E* e  {* @
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)) b% u+ s+ y# p
参数解释:8 y! r7 x, N& ]
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
  x7 p/ f" ]! \8 d7 tnReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
- l- [$ q5 \3 g3 i2 J7 f" C3 F返回值:
1 \5 a! d; M# ~& S: g# t1 Y' B返回非0表示计算成功,0表示计算失败有错误7 {6 m1 o: d3 s

3 j4 R/ \# H1 z' i
3 i7 H% k  y- x  W; T* S$ D3 |2 I  Q
程序代码:
# U/ h( p% ^% A: {! \9 Q& i) k* J$ g8 _! {) q! i6 R8 T1 e( T
namespace fy_Exp{
* L. F4 ]3 s# H) j6 O$ anamespace {template <class _T>
& Z3 }' T5 A' R; ]) [+ Iinline _T GetExpValue(_T t[], char& csym){
5 L+ |2 b7 O7 w7 i    char c=csym; csym=0;
: ^4 w  ^4 v6 m! F( @    switch(c){0 Y; b5 u8 p' @/ |
    case '+':return t[0] += t[1];
6 W8 v. H; n) F! _, B1 Q  L2 {+ f# `% x/ e    case '-':return t[0] -= t[1];- y; L9 J7 W0 q8 j% M2 k' B! ?
    case '*':return t[0] *= t[1];: s9 B& {; Z/ Q6 Z
    default: return t[0] /= t[1];//case '/':# n2 w$ I5 P$ I+ \9 V( I
    }2 Z; n1 p) ^' L3 n' n& P
}}
$ q9 ~, u0 |4 U- ~; u9 ktemplate <class _T, class _Tstream>
3 o9 j7 d8 K; s/* _Tstream: inputstream, _T: get return value2 M* ?3 e3 f" V* O% D3 q" k" C
* Return nonzero if get value successfully */. b9 H8 g* [: F' C3 _; F/ @8 S  b
int GetExpValue(_Tstream& istrin, _T& nReturn){
6 l# B6 U  _5 r: D, ?' o* y    _T t[3] = {0}; //雨中飞燕之作. A" {5 o) u+ F/ W7 u
    char csym[3] = "++";) p7 k) S& O7 a7 e4 C0 S
    int nLevel = 1, nERR = 0;
2 P" K) y9 ?+ ~0 [9 v7 X4 `    if(!(istrin>>t[1]))istrin.clear();3 b) G! Y9 R5 ]) k2 ^
    for(;;){6 ]. e3 X- v2 p# H2 u) a
        if(istrin>>csym[2]){
+ y( V( l8 Z$ t3 N9 v5 D; V            switch(csym[2]){
  q$ ~4 ~' Y, y* M) m" m            case '(':
- _' q$ S7 g! N% N  a, \& a                if(!csym[1]){nLevel=0x100; nERR=1;}else
: H/ b# M, b9 C) x" b) e                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;( r$ |, H# `1 T; r: W4 u, X2 F" E- {
                else{nLevel=0x100; nERR=1;}
3 E. {* \* h, P$ c0 B/ R4 h                break;0 F  ?* y$ k4 h4 h- I
            case ')':. B  Z# V/ p$ Z, f8 h7 w
                {nLevel = 0x100;}break;
3 d" @/ U: K  j& Q            case '+':case '-':case '*':case '/':
/ c1 w1 y2 e5 y0 T                {csym[nLevel++] = csym[2];}break;2 V& d2 J+ X* i0 U; B8 H9 r
            case ' ':case '\r':case '\n':case '\t':continue;
; Z' t  s' X9 R1 z8 s/ B1 ^' k            default:* {) A0 L  ~9 E5 `* H+ ]1 u/ n& F
                {nLevel=0x100; nERR=1;}
( r8 b, m: Q& D) i* C# z            }' w7 L2 n. Y' e0 c6 A. \
            if(nLevel==0x100)break;
$ `3 `% [+ ]9 u8 c, s            if(nLevel&0x10 || istrin>>t[2]){
; Z# G8 `+ b! m7 G9 n. d+ m                nLevel &= 0xF;' ^7 Q# c) P; R9 f
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}2 X6 V7 |' z5 R( M$ O+ n) a$ o
                if(csym[1]=='*'||csym[1]=='/'){
1 q' u; n. k+ v# A: g  ~( a                    GetExpValue(t+1, csym[1]);% n9 Q* ]: r/ W$ T
                }
: ^# Y6 {7 n( c5 R, Q; b                else{) k# k- k' l& A/ ~( r5 N0 J
                    GetExpValue(t, csym[0]);
4 n( }8 |% I+ J3 i                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;# C4 L8 I, _* s0 S4 b+ ~
                }' ]0 Q( z1 S, b( h7 b( _
                nLevel = 1;
5 p% x! F: b4 O7 V+ u* a" Z: m( Q5 A            }5 }* l% _* L+ B! W# F* l) [+ I. z
            else istrin.clear();) g$ m' X+ @3 P) o" h( B
        }
; \1 H/ n2 d4 ?* P( X" V0 O        else{nERR = -1; break;}
! B/ G. ]# t( o( [. w3 _/ }    }
: x3 z1 n' B7 t9 \, M; z5 y8 d    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);& _# k+ [0 t, \* B  k, `
    else nReturn=GetExpValue(t, csym[0]);5 \- n" _: b4 c
    return nERR==-1?1:0;
+ T# z# l! C: L7 y" @3 U7 D}}7 D1 i* v7 X% |

+ L- K* Q8 b5 s( E3 z' m$ U- T
8 B/ B3 f9 n+ Y# t9 G1 a
0 Q) K) i/ }% {- x: w函数模板使用示例:7 |& v; a. W; a8 r, f0 d! H
在以上那段代码的后面加上以下代码:& ~! W0 D, j5 U1 y6 [, }, K' I: {

/ s8 d0 S3 D( x# O7 a: ^4 V " I% y, W) m8 E9 }; |

1 \7 F/ y. p" c8 q% k$ `程序代码:
- U7 O, Z- _# o: n3 p
9 w4 i' V: Y! M, M& b#include<strstream>+ ?! N& t$ W8 ~  g: E, D
#include<iostream>
8 k& e  x+ X6 O0 m% w5 a#include<string>/ e- O  `% R1 `) k% `1 d9 o1 u1 M
using namespace std;: J  e6 ^$ k  n8 q0 S$ _$ p
int main(void)7 t; ^9 L# [) m: P: l3 e" d  m) E
{
# f0 U  t+ ]3 q! Q, q    string s1;
- p! z: N$ Z; P* \4 [" ]6 p# f5 W    while(cin>>s1)
5 P! W( W+ S  r" y0 \1 s& J9 b& g+ ~    {
2 c. u' z8 P& \        istrstream isin(s1.data());) g5 N- `# D' {3 W2 ?
        double d;
8 y" K( R/ }! V  r) Z: I+ A4 i        if(fy_Exp::GetExpValue(isin, d))
; o* n6 F1 D- g' Q        {  @( v( Q. x8 ~8 L% _: K. m# r
            cout<<d<<endl;
6 U6 U5 D* W- n. s# e) H" p- d. J        }& _0 C2 Z$ }2 [
        else
$ u1 j9 w2 p1 D, E: M        {# K" u0 r* ^6 J! y3 {# Z; O
            cout<<"ERROR"<<endl;
. w3 a! z  E$ c- v6 Q' ~        }
% }8 n/ ?! {$ Y5 I+ w    }* ~$ u* y+ M( t6 x3 a! _
    return 0;
9 V% }( k* j, [  H}
. {) `' S; N1 x4 p/ ]6 _  a# @
- F. h' T& T/ Y: A' p  [" q, }# `* I. Z5 ?, `: q1 I' S. w% d5 W
然后编译执行就可以了(*^_^*)9 i4 d# p  b$ e
其它:TC++上一定编译错误,不保证在VC6上也能通过编译
' [; j5 X3 ^& G+ h& R( B      建议使用VC7或VC更高版本,或者使用GNU C++编译

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