返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,) L2 S( p6 e" Y6 [, P! }# ?# I6 G
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
' I, I/ @% a& H% h/ t% J/ W$ ^只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)$ S/ M! x5 x5 E9 v
参数解释:
! W9 o8 q/ X4 Y1 N% fistrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
! Z7 X0 A" [% d9 H! P# d& MnReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
+ M9 r& _. f- o* f: w返回值:
4 o" |# |1 j) _+ I0 I+ O+ W5 X返回非0表示计算成功,0表示计算失败有错误
3 ?. V, n# W/ c( ^
. F! m! G; r; s' O! b
+ s! R4 @% R1 Q8 X
8 W# v% }4 P8 h程序代码:
4 c/ \# o1 T0 [; s! `- `, P% j$ m  ?  A( d7 G$ J
namespace fy_Exp{! C+ D! ], v' M5 v9 }/ G/ Y/ ]. Z3 z6 |
namespace {template <class _T>8 d1 O; u' y; E/ x8 h) L
inline _T GetExpValue(_T t[], char& csym){: [, `( o* W6 {
    char c=csym; csym=0;' z. |% k% s1 C: e0 q
    switch(c){
* [6 i- ], \& c1 V& D. f    case '+':return t[0] += t[1];
, N* n' w# U0 X0 F, Y& M4 j    case '-':return t[0] -= t[1];
* u- n  p  E8 G2 k% g    case '*':return t[0] *= t[1];5 V& E; J1 y  C# E& s5 @- w
    default: return t[0] /= t[1];//case '/':
8 }0 a' J; x# }* |$ C    }! j2 L% a4 u2 r% f/ _2 N( X/ m  b5 A
}}/ a- ~* e8 E3 ^7 @+ z
template <class _T, class _Tstream>$ z6 J$ l, N* O% y! a7 T- j
/* _Tstream: inputstream, _T: get return value1 W4 @9 a& ?7 f
* Return nonzero if get value successfully */
% R( Q. F3 _) t4 N/ ?int GetExpValue(_Tstream& istrin, _T& nReturn){4 K' T$ X! k% q* q" A- F5 g/ ~
    _T t[3] = {0}; //雨中飞燕之作
9 J" v9 v7 c. v4 `' F    char csym[3] = "++";7 d! ?$ z+ X8 l/ k, D( v7 m
    int nLevel = 1, nERR = 0;0 Y3 U  {8 T4 [% p" `' S
    if(!(istrin>>t[1]))istrin.clear();
& F2 }3 o' [7 E    for(;;){
9 @+ L" I/ U  y, {, |        if(istrin>>csym[2]){
* q- y1 L& ~5 ~! S            switch(csym[2]){
! A5 G# b5 k3 R, s            case '(':5 z0 I2 n5 _' ?3 e
                if(!csym[1]){nLevel=0x100; nERR=1;}else
& g3 g$ f0 |- m( }3 E                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
; Y: u1 N3 B. z2 o& x                else{nLevel=0x100; nERR=1;}$ ?7 M9 K# x" G! k/ ?5 }1 {8 N  h
                break;
$ q2 v+ _, o3 D4 R9 f; q. G( Y            case ')':1 v. S" `- k! N: t7 H* H$ F( Y; O- \
                {nLevel = 0x100;}break;6 a. C7 o& T: Q; g  Y
            case '+':case '-':case '*':case '/':
5 B, t1 p) D; [( ^                {csym[nLevel++] = csym[2];}break;* q4 a" N+ V( R2 w' |! ^# {
            case ' ':case '\r':case '\n':case '\t':continue;) \$ h% L$ y' R( u! |
            default:
$ K) D$ b. p4 p' R2 H0 O                {nLevel=0x100; nERR=1;}# a0 t1 r2 q/ m5 C7 \
            }# R, f" ^5 C- A6 j1 M
            if(nLevel==0x100)break;# Q9 F- C) L) D) ~; v
            if(nLevel&0x10 || istrin>>t[2]){( A  T. J: f3 g& i
                nLevel &= 0xF;
9 E/ h$ g5 |' c                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}) `& e4 W8 K. ?. a
                if(csym[1]=='*'||csym[1]=='/'){
. d" c6 U" V  ~& H  |( `+ K$ Q                    GetExpValue(t+1, csym[1]);
6 |/ D/ J2 Y4 T3 q  F+ O! m0 Z7 {                }2 v3 Z9 W& K2 U6 G* B* {( G. ]
                else{
  Y. D! E- G1 r$ L! b$ F                    GetExpValue(t, csym[0]);) Y& g; f0 w1 F8 l- Z; s  h
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
( @. z# Y2 ~' v( P                }5 L& d7 _, ^1 a3 F  q8 @6 `: P
                nLevel = 1;
" i9 n) r- R. l* g. w/ v            }
8 Z7 u6 h! s/ Z/ T            else istrin.clear();
9 M2 z5 e' L& S! v4 ^# W; N) @        }
8 n4 Q6 K$ G9 d& K3 t5 i7 d        else{nERR = -1; break;}5 t* x$ E! V- K* S, C1 K  @. v
    }8 G9 o2 s# V% D  c0 t/ e
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);/ ?2 v/ F' _2 _3 u$ Q
    else nReturn=GetExpValue(t, csym[0]);
& U7 i" h( k! W/ J8 |" n    return nERR==-1?1:0;
3 A" }! E- Q' O$ H: g% x6 ]}}
1 |6 J% _3 m) I2 n; ~2 h, c& m* L9 b' c* Y
+ y% d6 B' @% S# G

4 W( N/ G! G' R8 S: K5 G, ^函数模板使用示例:* d0 z6 q6 H; Y2 L1 ?( J8 @, B6 v
在以上那段代码的后面加上以下代码:
, x# {. [* d; x- E) H+ u7 ~1 Q
! _/ ^. D/ d7 K
/ E3 E* j; B7 C7 P6 z2 S9 @+ Y
! [0 t3 L3 D0 ?6 X& P  T3 I程序代码:
# H( G& H. i4 R; K) J
; S; d/ n8 s! W9 R; S" a6 W5 X#include<strstream>2 u( ~0 Y6 K9 y. S+ R
#include<iostream>
1 [0 l5 q( {- f: J9 T& e#include<string>5 d9 F( {( F1 f& C$ N
using namespace std;7 u" k) w% |, r9 P1 |. j5 D( |
int main(void)
% B5 X8 G& F4 C{% O# ^1 W) Z) T
    string s1;
2 m8 _! W, w2 F    while(cin>>s1)
/ D- c9 m( _% `) H1 {4 W    {
8 h" A! y3 a0 _# }, L( q        istrstream isin(s1.data());
% v8 A6 b) \! g        double d;
2 y, f0 p  n# T' o        if(fy_Exp::GetExpValue(isin, d)): N4 B$ p5 q) B# e' r
        {) u) f; r0 n1 s  U. {+ z- }
            cout<<d<<endl;
4 y1 S1 M/ q  q& w5 U        }
" z5 w* Q# C4 t* T/ m5 H8 w( T% X$ J9 V        else
$ P+ |/ E8 y  }" k% `4 Z+ E        {
% c- u" |9 a  d% h6 J* v+ I            cout<<"ERROR"<<endl;9 k" F" p8 N0 }8 l/ k
        }
4 \6 ]. y2 u) o0 H( ]6 M7 d    }+ `% d* ?: K% A& b
    return 0;, c- F0 z$ \" P  J/ x* q- D3 f
}
  s3 Q, r  [/ m* Y5 R) F8 r5 w. b9 N, y! M/ V9 D

) h: K# p. n) D+ c7 p( J  _  L然后编译执行就可以了(*^_^*)) N- D& H" x# S( Z' w' X
其它:TC++上一定编译错误,不保证在VC6上也能通过编译
3 a$ n4 s- R  e) @& K/ z7 r      建议使用VC7或VC更高版本,或者使用GNU C++编译

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