返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,# p# K* M" o, E# H
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
" s3 }: J" U  e只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
6 d$ N2 N/ G% i' h0 V* @7 {" }参数解释:
2 L- R; V: D+ l( [" vistrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流( H2 o5 b# w  N5 I: G, L5 E$ c
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
6 A6 \8 \3 w; h( ^返回值:! a. c: f2 W+ \4 s# S# C# R
返回非0表示计算成功,0表示计算失败有错误
3 q3 V9 }% h0 R+ k8 Q
) `; e. Y) |! S" K& g' I6 W
& f& Z. G' Q. E8 Q( f# l
1 u% R4 u9 T1 W: t2 F. F0 m0 J程序代码:
( _# z" Y, r# R1 H4 f; n" @$ b
) N# S# D0 w5 {; i( m* ~" c$ Lnamespace fy_Exp{
& L$ ~8 D. ^: Z6 a4 \namespace {template <class _T>) `% N# m" Y$ l4 ]& E# X( Q3 B
inline _T GetExpValue(_T t[], char& csym){: d, q' E) [9 R' F# t
    char c=csym; csym=0;
' I! M( |& r$ \2 M/ y  x5 @    switch(c){
1 w5 x' e$ e% u  x# L7 y: Y* B    case '+':return t[0] += t[1];
  e0 P; ?) t9 Q1 ?- l    case '-':return t[0] -= t[1];5 g8 }( R2 E9 t# q1 |. m
    case '*':return t[0] *= t[1];
0 W+ I& v. k. D. y    default: return t[0] /= t[1];//case '/':% K& O! P9 ^# P: U" Q
    }% ~1 j  w) }0 A" Y$ p
}}  X* n, M5 ~1 n  D" [  J3 T/ f
template <class _T, class _Tstream>
( c% |0 ^) X! p' F  h( V) Q/* _Tstream: inputstream, _T: get return value
1 Z* A" d$ w+ V" O8 [: m* Return nonzero if get value successfully */
3 z5 T, p5 U4 u% Q1 V' Y" Sint GetExpValue(_Tstream& istrin, _T& nReturn){8 w/ G; t8 Y9 u" [
    _T t[3] = {0}; //雨中飞燕之作
. i9 y& y/ N; Y3 P+ V8 {    char csym[3] = "++";6 h# k" P* H4 c& P  X
    int nLevel = 1, nERR = 0;
! D5 |$ c1 _3 k5 v    if(!(istrin>>t[1]))istrin.clear();: u) d! F9 F: A
    for(;;){4 u" G+ @2 Z2 [  _0 `
        if(istrin>>csym[2]){. T% f+ k: f4 k+ p3 Q
            switch(csym[2]){
, O, M; v! y5 @( H4 z2 t$ ?; R            case '(':
7 b" K1 w; [4 X' ]; Y: k                if(!csym[1]){nLevel=0x100; nERR=1;}else
9 {' e) Q0 h* E; L- Z2 l- Z: n) m                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
- G! c  Q1 o5 G9 u$ C                else{nLevel=0x100; nERR=1;}- Z6 L  E6 g! W) i1 Z! X( G
                break;; V3 h2 f2 u8 E" k& W
            case ')':
( T! R; u3 t( X" @/ o2 u+ Q' T                {nLevel = 0x100;}break;
; d0 ~/ B# N+ w: o& n7 A            case '+':case '-':case '*':case '/':
6 L# ^6 E+ q8 A- Y* h# y                {csym[nLevel++] = csym[2];}break;
' r* t) H- {6 X0 B- a7 f            case ' ':case '\r':case '\n':case '\t':continue;) y  v- U5 _5 \
            default:+ P! x$ e: u' |% g: c
                {nLevel=0x100; nERR=1;}
; T- `' l% H7 F- f& V/ n            }
; u6 _1 b$ D/ K6 j            if(nLevel==0x100)break;+ n; u, s/ a7 P. O5 k! _( l
            if(nLevel&0x10 || istrin>>t[2]){
) u1 Z$ E1 Q" T                nLevel &= 0xF;" D1 ?3 c; x" P7 h6 ~8 i1 u
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}2 u; N6 m" x2 z; e% X, F4 O+ \
                if(csym[1]=='*'||csym[1]=='/'){, A9 [% L! N; _4 ^* C  a
                    GetExpValue(t+1, csym[1]);% C/ V. e4 u4 r. S' P
                }( g" n5 I+ U5 x
                else{
/ N1 t* b5 T( `                    GetExpValue(t, csym[0]);
  C3 a8 R+ {+ E# h( U$ [                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;! @# X5 k$ G& L" P
                }0 l& x  a' z% D. b' ~( {) c
                nLevel = 1;8 V/ e- e' T3 R( z8 y4 `3 w
            }
- A8 ]: d! I1 U! {, ]  D            else istrin.clear();1 ^8 ~3 D2 e2 W. x3 K: P- V& B
        }& |) ~/ n% c& A% J
        else{nERR = -1; break;}
% l4 z" u# [/ q2 c8 E    }' B6 @4 @0 d, a/ B* p) C
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
8 s% ]$ l& ^5 G# C    else nReturn=GetExpValue(t, csym[0]);1 |- |+ V- H4 ?2 c) D6 U
    return nERR==-1?1:0;5 x9 s& p( f/ J: t: T
}}8 Y/ ]( r- ^  r/ @( Q6 v% I
; ~( t% p, V$ Z9 Z1 p& }* i' y

0 k& N' d* d$ Z! O( d
9 k- d5 V. l2 R- L# n, D7 a: k! [3 x) O! G函数模板使用示例:5 ?  r9 [1 G- G0 s; g
在以上那段代码的后面加上以下代码:" |. S& ?: B& H, z

( x  F. _/ [' y0 F
3 N( ?1 n+ O0 a% U# E( Y( n2 g: x8 k/ y7 \
程序代码:
/ r5 }4 v( v' r1 i+ w) r( m
" W% g. }! p; ^- g. f8 b3 v) b# y9 w#include<strstream>
. f" F7 k) q/ ?) \  @' ?! T#include<iostream>$ s% I5 W7 [; ~' o; M5 T! B) g& m
#include<string>
8 E, X4 h5 r0 N9 zusing namespace std;
, J! r  a+ P6 g: a- Z: |3 Mint main(void)
' C9 N) v/ |  Q- D: j# K2 Y# ~{
& B$ {' L! ?, d2 S  g$ T    string s1;0 z1 F- x+ h5 q4 j' Z
    while(cin>>s1)
$ ^: P6 A9 Q1 L* ~    {
- |9 M6 [5 p- u. |$ W        istrstream isin(s1.data());
$ D- D: ~) f0 M9 ]( G1 V        double d;
4 m, {4 Y# O; L! x& ^8 \" x% ]        if(fy_Exp::GetExpValue(isin, d))
* X0 N1 A7 f5 t7 e, ]" D: I9 E! g        {
" Q0 ]3 u. y" g            cout<<d<<endl;
4 [; e/ Z% H( g' n' f        }+ M5 F" N! @8 G* F3 U) v
        else
% }/ B1 |8 O: A- \2 ?/ Z: S        {$ c5 g) @; r; g( `0 U3 V
            cout<<"ERROR"<<endl;
) ^: p4 L2 v: n: y4 L* A        }
% J' A: r  _$ s, O    }  `0 U/ Z# `& G7 ~
    return 0;; ]+ B5 T  l9 {* W$ V$ ^
}
& Q' k3 H/ N3 g" f  g6 X9 A" T# K& P2 C) P
2 e# R6 a' ?* M% @- c
然后编译执行就可以了(*^_^*)  {; q) s' o$ E3 B6 J
其它:TC++上一定编译错误,不保证在VC6上也能通过编译
( j, r; I1 B1 c4 J$ i      建议使用VC7或VC更高版本,或者使用GNU C++编译

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