返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的," y2 }* W( u7 _6 I0 A
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式( L" X- `+ }. ]" U
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
0 _+ E2 z7 X0 q* M% K3 K参数解释:' m* [0 B, O3 H# y  t
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
, _# x4 h: r: EnReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定/ Y4 l# K. K5 l# ~( `$ L
返回值:
( Y1 _" q: i0 F1 b, t返回非0表示计算成功,0表示计算失败有错误/ g* h' {4 b& d) v0 }2 X

6 B# M5 n( }* e7 R
9 X5 [. C5 S6 j- U$ o0 n$ K
9 Y5 u, c5 d! G! _+ O  @7 R) V+ F) z: t) I程序代码: 3 X! V5 d1 p/ R  H' `, |$ S2 Q
: c) z' U8 `* c: S# [
namespace fy_Exp{
8 e' @  m& l( O4 S1 Wnamespace {template <class _T>  {' H& h' M3 D" |# R$ e
inline _T GetExpValue(_T t[], char& csym){+ v; x. o$ m1 x% u& k
    char c=csym; csym=0;  [2 b7 A' ^8 _$ ~& @
    switch(c){- R3 w5 r' N+ d* O3 r3 z
    case '+':return t[0] += t[1];8 K0 H# T/ a/ I! o3 q' g% w
    case '-':return t[0] -= t[1];
# M3 A) \! {& k) O- j    case '*':return t[0] *= t[1];
& O/ y' A; D) M; @    default: return t[0] /= t[1];//case '/':1 q8 L3 ^: [, X; c
    }, C# {' L" Z* l. X/ n% R
}}+ @& N" w: {, G! s+ z+ j4 c
template <class _T, class _Tstream>
9 K) J5 F1 d) B) _0 E/* _Tstream: inputstream, _T: get return value
7 g2 c% B2 ~" l8 n/ T8 b* Return nonzero if get value successfully */
- b/ T5 Q! F; v6 s8 Eint GetExpValue(_Tstream& istrin, _T& nReturn){
7 {/ X2 o" g& j" d    _T t[3] = {0}; //雨中飞燕之作9 j# i! f# Y- W: }2 l0 I4 O  S) r
    char csym[3] = "++";( J1 ~; c0 a1 d2 y. J
    int nLevel = 1, nERR = 0;- Y- W: w6 q/ Q1 R( N/ n
    if(!(istrin>>t[1]))istrin.clear();
0 n0 T# [! X' D5 Y+ ]+ U, {8 n5 g4 G2 k& ^5 G    for(;;){# ?' Q: j1 T+ d0 S% A
        if(istrin>>csym[2]){
2 u5 l/ j9 H0 }: L( V            switch(csym[2]){
0 \( d3 Z1 N& r            case '(':  d; S( \  G$ d
                if(!csym[1]){nLevel=0x100; nERR=1;}else
$ R) i; K/ a! `; U5 x% Y                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;" v& Z; c, o( D0 I" S( f
                else{nLevel=0x100; nERR=1;}" _, Z4 G) P. D7 ^* L
                break;
" Y6 P9 e' ~% g, R% F+ q            case ')':
3 ~* r) }1 }# f. X1 k# [                {nLevel = 0x100;}break;/ T; X3 v: @% j' e/ h* Z, a- m
            case '+':case '-':case '*':case '/':+ r0 J( F; e& F% ~; e- ?
                {csym[nLevel++] = csym[2];}break;
* n. O) A: _/ {! ^4 Q6 E            case ' ':case '\r':case '\n':case '\t':continue;2 C! E. Y2 x! c
            default:
4 B+ k; d4 l/ ~; q" B                {nLevel=0x100; nERR=1;}' o. J& y  p: X  `5 n
            }; c0 I' k. ^0 [( S: q8 y: i$ S1 I4 \$ o
            if(nLevel==0x100)break;
0 ?. ]5 ?+ x( R" q# F: e! x! d            if(nLevel&0x10 || istrin>>t[2]){$ ]# r: O6 b/ ?* p6 W
                nLevel &= 0xF;
1 C8 l5 B! G/ k# }( X                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}+ z( C; I( J' h3 u% I
                if(csym[1]=='*'||csym[1]=='/'){
  N; D9 q' \0 I5 }" Z7 c                    GetExpValue(t+1, csym[1]);4 w' v+ L7 P# R6 D& Y  ?1 ^
                }
8 p  T- S. Y/ o4 l8 m) H                else{
7 j8 l5 x! a3 ~$ i                    GetExpValue(t, csym[0]);0 u# b, T- t. O: F
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
4 Y- z) b3 Y8 a( I" m& z5 l2 i                }
& Z4 C% }7 x  }: Y: \7 B                nLevel = 1;
- \1 e. t7 p; O5 B0 Y0 _            }
, ?: A% \" u- j            else istrin.clear();
% H5 Y5 ^3 V' e; N4 w" r6 _: f        }. A, E* ^# \4 ?$ @( W8 ^* t
        else{nERR = -1; break;}3 P$ T6 W+ {5 ]4 H$ t& ~' I" z
    }9 {0 a& V5 T/ _: l5 y/ |# [
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);( G. P9 ~" c6 C, w9 D% W  j# L! {, c
    else nReturn=GetExpValue(t, csym[0]);
9 U# I1 ^# b1 _7 n' a6 m    return nERR==-1?1:0;
; r; ?8 O/ f3 |: ^( u9 a9 c}}! B. s, Z, B  G$ L" V$ R

8 e% X; |: ]7 ]: ]- r/ D. ^+ R2 ?7 _- \/ T) q( w

4 S6 m* V1 I* [  r6 T% p) |函数模板使用示例:
  ^" G  B( @: V# Z! O在以上那段代码的后面加上以下代码:
6 b! x7 }" @+ T4 B7 g6 ?
7 a; E0 _0 @1 R$ P 7 P' C8 `4 e# n7 {$ g3 o
2 r( l- x  m, h1 p, v/ K: ?
程序代码: / O) f% ]* F0 L8 g& H% X0 ]$ v# T9 D

: G8 u, ]8 n/ s. X  f$ d- M#include<strstream>( m7 \  N' D: e* U% @+ i/ s) |
#include<iostream>& V) Y, F2 P# g" x; z# N
#include<string>6 Z! p2 [# N* r) X
using namespace std;% U$ x( N+ z5 o7 [5 }) b
int main(void)
2 S+ p! M1 W, f% P: ]{# f1 N  c9 l& f
    string s1;. e' D; b1 D' @& b/ \2 M
    while(cin>>s1)
* @; h+ j% {& F( ]* @- Z' Q# }    {
* u# B  V' y* X# V# K3 N        istrstream isin(s1.data());
8 u* |9 F& X  _; ~" r        double d;
; m- ?- N& ?+ T  A) ]        if(fy_Exp::GetExpValue(isin, d))7 T8 K! |+ H( M/ P2 b' {5 ^
        {) P1 i6 d# |. ]/ F8 B/ A+ ?! Q8 ]3 W
            cout<<d<<endl;
( I' |0 B7 D" x/ `  `        }
+ C5 L7 b3 J8 b$ V% l        else
6 j: E" I" y8 \        {, `  X# u* R+ @, G+ [; J9 x/ y
            cout<<"ERROR"<<endl;  o2 f( N3 l+ z  a. r
        }: T9 ^) r+ |7 N# Z* o; d5 ^
    }
& o0 w( t! u, U    return 0;
" X+ k1 e3 `: A2 d% U! I) u6 y}
8 `. W& E+ o  l3 x
5 [5 I" T5 j2 l, J5 D: U1 {$ A  @
3 Z* ?2 h, h: q5 O& e, F* R然后编译执行就可以了(*^_^*)
8 j6 D7 q+ |: w  S4 z其它:TC++上一定编译错误,不保证在VC6上也能通过编译1 ~9 P* S8 W: ~, M: k6 K* T* u
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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