返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
& y. z  F9 X' L$ u/ k: \一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
) N) u4 L  B& F  [- i" {  y只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
; g3 Y% _  m0 o1 N6 }) J参数解释:
. F: s! ?$ k- I3 E  M5 G0 Fistrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流7 I3 Q; W" y) v* _, M4 Y% a
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定# U( P0 }& o: t6 L; ?% t! X# _
返回值:5 O6 H0 t; V2 C6 W# d4 i9 S
返回非0表示计算成功,0表示计算失败有错误8 b; J4 I; b# @8 Y6 g  g! m
# s; W; C' l" A
  x% l) s, Q9 D, [3 @, i! e* |

3 L2 {# A& ]5 y& {程序代码: 7 N/ U  @& a( a* V3 ~) v& j
2 U1 X+ c  w. w" ^, L
namespace fy_Exp{! u: ]) s5 T/ a5 h, f- W
namespace {template <class _T>" R; P: {( L7 j3 |# e
inline _T GetExpValue(_T t[], char& csym){# e( c- @" P- e" {' \8 P" X* N) F/ g, a
    char c=csym; csym=0;
3 k  [9 U. R  {/ L3 k    switch(c){0 d, a. ^* M  _, [
    case '+':return t[0] += t[1];& y$ h  z1 e) T7 [* E* z; @0 Y& G
    case '-':return t[0] -= t[1];
) W* P% i6 [5 n3 @1 L2 t% y    case '*':return t[0] *= t[1];1 U" l  _) S& M  c$ ~% X
    default: return t[0] /= t[1];//case '/':2 i5 R9 |6 t# Y# C
    }
1 {5 M, S$ E  I3 f0 g}}! V/ V# P8 u. _
template <class _T, class _Tstream>5 R. l" I2 v1 s1 A
/* _Tstream: inputstream, _T: get return value
/ s8 H; ?9 a1 Y! |( C4 `* Return nonzero if get value successfully */
4 N7 y+ P$ f! r5 N: @) [! Dint GetExpValue(_Tstream& istrin, _T& nReturn){1 e9 G7 f$ k7 B; y; x5 p8 |
    _T t[3] = {0}; //雨中飞燕之作
  a! N5 u: ?8 K( q  Q6 N    char csym[3] = "++";
+ l: R: B# e4 e( A- }% @/ E    int nLevel = 1, nERR = 0;: _+ {' @* [7 q1 }
    if(!(istrin>>t[1]))istrin.clear();% c8 O  G: m5 R3 n' ~6 Q
    for(;;){
% p/ K) Y% A7 S2 M  g        if(istrin>>csym[2]){9 ]) g2 l5 W" z  t& T& B8 p
            switch(csym[2]){( f1 j6 Q" {- C+ a- u0 l$ y4 t
            case '(':' J* e. l/ @% v! z# p: r  H) m% g
                if(!csym[1]){nLevel=0x100; nERR=1;}else
$ E; U( F- i4 S, f/ @                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
! U: J4 I; p0 i0 m( N                else{nLevel=0x100; nERR=1;}. m$ x! ?/ q9 R  V% g! ?: n* q) z
                break;; B% m# s5 v7 d) @7 J* }
            case ')':
( J8 H# a: W5 p( J                {nLevel = 0x100;}break;$ B- |: j# `( M2 r# R% E
            case '+':case '-':case '*':case '/':
1 h+ G4 B% `2 j2 P" K+ K                {csym[nLevel++] = csym[2];}break;
! q) x6 Q) F, T6 X! d9 ?: \            case ' ':case '\r':case '\n':case '\t':continue;2 h8 S- E5 a% F; C6 `# K
            default:8 b- q1 s  }( i# V/ \/ l7 L2 o; t
                {nLevel=0x100; nERR=1;}
5 v6 q  S9 K: k            }
7 v; \8 T. ^' T& Q0 @            if(nLevel==0x100)break;
$ w# s! d  J8 v& f4 U) [! V7 V            if(nLevel&0x10 || istrin>>t[2]){
  Q% W" w, e, C* ^6 E! u                nLevel &= 0xF;) _. T& }' X. i) q. r9 y2 x
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}* ?: R# k4 ~0 z: |5 Y
                if(csym[1]=='*'||csym[1]=='/'){
& ]& R3 R% v! C9 J                    GetExpValue(t+1, csym[1]);
5 {) Z8 D$ ]1 F# g* Q                }4 k/ I$ R: H. g6 |. S
                else{
& M& E7 f; Q" d5 Y9 H' T5 y                    GetExpValue(t, csym[0]);/ Y4 e5 }# {( K3 n/ H% A% P; b
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;5 b% X6 }; `5 k% K9 r
                }
( H5 f0 u# e' L2 C                nLevel = 1;2 N5 w' F/ D' L3 Y
            }# d- D2 u) |, k% g& ~8 m
            else istrin.clear();
. m- U) ~; c9 R! k2 {+ f2 @        }
5 f# d8 v+ J) ?0 n7 _, \- y        else{nERR = -1; break;}* F* H" x8 R: v
    }
8 _* ]* [( ]9 ^5 b" M, G    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
. L& b6 {- b; v" [# Y! P    else nReturn=GetExpValue(t, csym[0]);% n9 Z: ]! N2 B% S6 V  ~  q, r
    return nERR==-1?1:0;5 V) J& O. Q8 D  b- \; G% D
}}1 i' u+ H6 ~! w' E
, y, i# F+ f3 b
6 x/ n9 y6 v- W( w) E# S' T3 @; R7 X& k
; l: A8 _+ ~$ l( y' ]) b7 X
函数模板使用示例:
+ Z& b  `/ {1 E4 d% g在以上那段代码的后面加上以下代码:
" [& {# e$ w4 l4 o
, j$ D7 b# C' i& S( Z
& J7 W" s5 y! s8 U) C8 f& r+ W. [' ^
程序代码:
. q& C) N* L( D! E, u0 U+ o0 q* d9 z& _& C
#include<strstream>
- a0 s0 R  N$ @' o' v+ F/ ~#include<iostream>
  i4 E0 F. i2 i#include<string>
  I. R( I* X8 P; w7 D0 g* k" ^using namespace std;; Z$ W+ W. ?( H" R" y% w
int main(void)* a8 V& W$ G" F! f. K9 J6 P
{
4 O/ i( w+ s  s8 Y5 o    string s1;
  `* f/ {& t( Z9 B3 q* P$ t    while(cin>>s1)
' g+ f) f0 a1 @5 N0 E4 \3 @    {. x, T( B. m7 Y4 U* i
        istrstream isin(s1.data());; o- b; e; y- e. K- i+ W% A
        double d;% F; F* y3 d/ q9 K/ R( a
        if(fy_Exp::GetExpValue(isin, d))
7 ~& r2 ~- `; p$ N& r/ }        {, V7 F4 S# R$ p* N) A, p
            cout<<d<<endl;# M: C8 W: e7 Z/ M7 X+ h
        }
1 W: r2 K- x8 l" g# [        else
; s3 V7 w1 h7 F! N, \5 M. O7 Y) d" I        {
8 ]0 h2 V3 S5 F5 C            cout<<"ERROR"<<endl;
7 e: W" ~+ j0 O" D& K7 X, e        }
2 _' `1 f1 U  E! d    }
. g5 T+ t0 C  x    return 0;
! l6 a4 ^5 z. C' Q; Y}4 @, l7 O6 a4 T1 {4 R$ D
4 P4 Q/ l& t+ U+ T5 Z
5 {6 m8 I0 ]6 B( G& n
然后编译执行就可以了(*^_^*)( ~- k7 ~% X6 r6 ?& u
其它:TC++上一定编译错误,不保证在VC6上也能通过编译
2 {4 M: `! C1 f: ~      建议使用VC7或VC更高版本,或者使用GNU C++编译

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