返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,( g! B' P& q- l: p6 w
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式( l( H0 @% [! N  X4 B1 r: x
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
: W9 n  C" l. w3 l2 j! M: Y( W参数解释:1 b* S1 p1 t) Y9 |$ Q8 m- n- F( f$ N
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
* w  I* `4 d" DnReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
/ z3 |" M" L; e" `& ]返回值:
- r: `. m' I/ u& G, c  c3 j返回非0表示计算成功,0表示计算失败有错误
2 \4 K7 d6 w' I3 O( X) ?3 v, b5 O' q* ~; D7 o
: W5 {! O/ @. J& A7 I) b+ V

1 s4 E( v+ _. y% h, L8 `5 s( Y程序代码: 1 w8 T5 o5 c; I) a

; |4 o8 }* G* ]0 H! O" `namespace fy_Exp{
! _. o$ C" E" C7 E- I; R! W9 R$ U: Vnamespace {template <class _T>
. x( g* ]- U9 finline _T GetExpValue(_T t[], char& csym){4 k1 R: O, m1 O* ]9 A9 }
    char c=csym; csym=0;
" R# ]# v& e- C: P8 b3 @2 n4 Y/ r; B    switch(c){+ q( a+ J' J7 r' X2 @1 ]+ t& n3 o
    case '+':return t[0] += t[1];
2 Z, }' U) W2 W& P- V+ \    case '-':return t[0] -= t[1];+ W; x  Z2 S2 P
    case '*':return t[0] *= t[1];! j8 D) g$ z6 C7 M4 M
    default: return t[0] /= t[1];//case '/':- X2 e( N- @' u- D
    }
, J( m- o* `9 a/ e$ P8 v: x% S}}( _* M) v  q4 G8 h
template <class _T, class _Tstream>+ x) \6 D/ x5 e! r- X8 v
/* _Tstream: inputstream, _T: get return value
7 g+ }% b6 ~* k2 [' S+ z1 d* Return nonzero if get value successfully */
; A# ^( e: @6 c' \" T2 x5 H) cint GetExpValue(_Tstream& istrin, _T& nReturn){
2 J2 u5 T; v) Z( J    _T t[3] = {0}; //雨中飞燕之作
  y* ^7 g, j! L! [    char csym[3] = "++";& x+ C, i* N: |- b
    int nLevel = 1, nERR = 0;% ~8 \- m" C% b# d+ b
    if(!(istrin>>t[1]))istrin.clear();' u; L2 `8 A- e7 x7 n# ~, B
    for(;;){4 h0 O  A/ r( K% m
        if(istrin>>csym[2]){
2 e& ?* W7 G$ c3 T1 c4 J% r3 w            switch(csym[2]){% ^* O! N, G) Y5 O3 F
            case '(':' C  l8 |, e  @7 _2 C
                if(!csym[1]){nLevel=0x100; nERR=1;}else
  z, P9 [& v  _% w! I# s                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;* [: X+ h8 y  h8 ]+ X
                else{nLevel=0x100; nERR=1;}
! [6 S% I5 M4 o, r' r" C$ K$ L                break;
; w; d( ?& }5 C% g) Q& N            case ')':3 G( I  A3 j# Q0 _; B1 e
                {nLevel = 0x100;}break;. j8 p# o! T5 J7 A+ T
            case '+':case '-':case '*':case '/':; o1 N  L+ V& H  ~/ q/ q/ ?& C9 L
                {csym[nLevel++] = csym[2];}break;. h  S% I' t. q. K6 n, y
            case ' ':case '\r':case '\n':case '\t':continue;
% ]9 `& U3 r) k6 Z            default:
) T- G# B. D, d# o" D                {nLevel=0x100; nERR=1;}
0 @! G% [3 y* i  O+ l5 \            }
+ `. T, L. f- I7 N            if(nLevel==0x100)break;
! N+ v% o0 U( `) _+ q( }! h            if(nLevel&0x10 || istrin>>t[2]){8 G/ h4 v9 v  h4 Q# J
                nLevel &= 0xF;9 ?; b6 L8 R( O& M' `
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
0 i6 Y3 t) j9 u) V0 q                if(csym[1]=='*'||csym[1]=='/'){
0 K- q! j7 g- G+ H& [                    GetExpValue(t+1, csym[1]);
$ t0 h5 c& n% b                }
. o+ ]5 u2 o) p- y  h                else{
* P5 P# P, C, o0 Q* g2 J; v$ {                    GetExpValue(t, csym[0]);0 D4 {& X- U1 f; K
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
: S. G: k& q( I; [9 M( [6 i! b                }
( }* y0 Y3 x' S                nLevel = 1;, M2 g) F& D% W6 W- {1 Q# m
            }
. u, H+ p+ ^/ l* w- c8 E" d6 r            else istrin.clear();
+ R6 e& I  r0 k2 ^        }" e3 d3 N5 x( r9 ]5 B
        else{nERR = -1; break;}+ b# r- S) t0 e. o- k
    }
( r0 D" |% n* p: Y& ^8 a( J9 H6 `    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
* ?' Q  G9 E; R- ?' Q    else nReturn=GetExpValue(t, csym[0]);! b5 t( E7 L* I1 B) r! ^
    return nERR==-1?1:0;
/ k3 t$ \' N7 s$ Z}}0 j; y% a: C, Z+ E
9 F9 B0 a3 m- u/ G7 A% U! r& {* A
2 Z% Y1 T% e. t6 k
1 `9 E1 D9 m5 e, q3 k
函数模板使用示例:
/ f, X7 q. C0 O在以上那段代码的后面加上以下代码:
1 [( I* h/ ], D9 A4 {
! S5 m- H% F7 |& x) j+ T
" F9 V) O  G8 D' _- M: C$ t& {4 S$ I" W+ U
程序代码: ) f" [0 J: {) P0 u7 l* z
$ U! s4 u% a5 h8 ?2 b. t9 C  E/ I
#include<strstream>
3 X: Q2 S3 D. \" `9 c#include<iostream>
, b: P1 t5 J& P3 \( O. @' u#include<string>" E: g* U( s& y
using namespace std;
% n  D& r) g  O( y. Y- Eint main(void). S% L% c/ I  i& E/ A1 F$ N- F9 G
{
; W* E3 g4 ~0 |$ H7 r    string s1;6 M4 J2 |+ K! r9 ~( P$ Z# Z* X& U8 c4 [
    while(cin>>s1)$ @7 q) _) [" k! S
    {; A8 c. q0 M+ v& O8 L7 J# k: h
        istrstream isin(s1.data());$ W5 `' T: @' y" U/ b1 {" R
        double d;, j! f3 [4 P$ E1 R" {* u& X
        if(fy_Exp::GetExpValue(isin, d))
2 E; l9 g$ |0 L1 w6 u        {
" v3 Q0 }, w+ I. F% u" R- ]            cout<<d<<endl;2 R) ]: o5 }9 J) H' t5 j) X
        }* ?- r  y9 W& ^& x% P) F
        else
4 Y% N$ }) @2 [        {8 H) I$ c. ~, D* e2 r6 g
            cout<<"ERROR"<<endl;2 y' Y3 H" e" C4 P! R; E
        }' F1 \* ^5 d# I2 Q  r  l/ y) o/ `! G
    }! f* V+ K+ J6 A+ ?) e. u
    return 0;
& E) ^+ a. u1 |, e6 d, n}
: J5 V9 S+ z* l1 e' y
0 U! I8 Y9 I, b% K* q/ ]* V7 Z  S" G- f% ~$ W
然后编译执行就可以了(*^_^*)/ e1 Z5 _+ U4 `: O1 ^
其它:TC++上一定编译错误,不保证在VC6上也能通过编译' Q. A% g, E1 ^/ y" F$ d9 y
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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