返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
0 Q& [, W3 V, e- ]一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
7 _" d( O% h9 v* N" Q6 j" y只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
; B/ X8 |: B6 `& Q' N( F参数解释:
6 K% W  T2 w$ _- N- [4 vistrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
/ {5 t( @3 M( m% s0 Q# BnReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定( M5 Y5 v/ g1 H! Z6 c
返回值:% G9 ]9 x) N1 y7 Z
返回非0表示计算成功,0表示计算失败有错误
( Q8 N2 ~* M# t: S+ z$ V, h+ C6 O$ _9 O9 X2 z
+ c. m+ `$ z% t# z. R; j+ ]
4 k9 p" r7 Y* ?! m- W: k, \4 Y
程序代码:   |6 \  u  ^& p# a+ _4 u9 R

) _& P- B1 Y6 R* @7 ~! \7 f# m( mnamespace fy_Exp{2 C2 h* n1 _' S& ~6 ?4 z
namespace {template <class _T>4 l4 h$ j: R4 H  C
inline _T GetExpValue(_T t[], char& csym){
+ C6 E3 W7 Y  l- Y( p  h- D    char c=csym; csym=0;
7 E, K; n5 f. A; }0 F    switch(c){
& U8 R( g8 Z- \5 d    case '+':return t[0] += t[1];7 y$ g. d9 f4 G! Q
    case '-':return t[0] -= t[1];5 t  E% _% H' E1 @
    case '*':return t[0] *= t[1];
* K: x; j2 J  S    default: return t[0] /= t[1];//case '/':2 J' s& r. R1 f/ p; h( p
    }( x/ p( v, p. X' o" [
}}
( y1 z$ \* H: `9 Z4 Ctemplate <class _T, class _Tstream>3 Z6 l3 [* }" t2 }
/* _Tstream: inputstream, _T: get return value& y! D9 H2 b; }! B
* Return nonzero if get value successfully */
# _7 \: Y7 L" u+ ^4 I& a: N% t# Oint GetExpValue(_Tstream& istrin, _T& nReturn){
; O# m  G( y4 e7 s% q/ X4 q: r    _T t[3] = {0}; //雨中飞燕之作
5 H) I! U/ N+ I9 ?3 i# D2 |    char csym[3] = "++";5 b' X# Z! }& Z4 I4 B9 r9 w: N2 _
    int nLevel = 1, nERR = 0;
& D0 e- T; {9 F9 q1 S6 [2 \7 h  E    if(!(istrin>>t[1]))istrin.clear();5 {& K% _0 i) t/ {" ]
    for(;;){
, V2 q4 F9 N+ \0 R% d. Z        if(istrin>>csym[2]){- B+ b. j9 n4 _: C+ L
            switch(csym[2]){8 G: H0 D$ Q6 @( {1 n8 S) f
            case '(':5 h  [' b2 @6 }4 t* Z+ ?% m! r8 U
                if(!csym[1]){nLevel=0x100; nERR=1;}else
& B' u+ `" Q; R( }                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;* k9 v- Q( C) x  f0 ~1 y2 |
                else{nLevel=0x100; nERR=1;}0 I8 x. N1 W: Z; }: r, [7 s
                break;; ~; H  ^  t& q3 B% X; b. p
            case ')':5 f! q6 h* h9 v4 G! n  @4 L$ f
                {nLevel = 0x100;}break;4 m1 a0 c& l3 `3 R* f9 n
            case '+':case '-':case '*':case '/':
4 d( Y# x- h- q1 X5 T) g( z                {csym[nLevel++] = csym[2];}break;
. @' e4 q6 _# Y* h, U            case ' ':case '\r':case '\n':case '\t':continue;! l+ W: G* J/ ^9 n
            default:
6 {# _4 q. w, W3 d# d6 Y0 f7 K                {nLevel=0x100; nERR=1;}
3 A# V3 q$ y4 j" ?            }
6 w4 A+ X6 r, X            if(nLevel==0x100)break;
2 E% d1 B& D1 z! P7 f: t+ V3 p            if(nLevel&0x10 || istrin>>t[2]){: K; C+ W: {# b7 Z# O: v0 s1 f
                nLevel &= 0xF;
' r8 o7 h: Y! t2 Q                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}: Z9 \" t) D1 v* C/ w! P
                if(csym[1]=='*'||csym[1]=='/'){0 d3 A2 f& ^2 x& P& V3 n1 c
                    GetExpValue(t+1, csym[1]);; y4 N' z- F  v7 `) A
                }: m5 R" x& c) B0 @- Q' ^/ z
                else{
* ]! |) O0 M" ~# ?# m                    GetExpValue(t, csym[0]);! o8 i8 ^+ x- b
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
8 A6 `1 S3 _5 o$ G                }
) [2 o9 M5 x+ q' m# [                nLevel = 1;
( ?% A  o/ g5 |$ b& @            }0 n' Z# p+ ?- X" n
            else istrin.clear();6 _! f3 F1 a9 T6 p, a# y# _2 w4 @
        }% k, b! F% V( u. c
        else{nERR = -1; break;}9 A% t3 \9 j0 M% p7 r/ q% f1 ^/ H7 H
    }; `# c# q$ s+ v' f9 r1 f0 d4 H
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
' U1 O# X! y9 g% b# l: a    else nReturn=GetExpValue(t, csym[0]);  m2 e4 u; M: C1 @9 V8 d& a/ X: w" d
    return nERR==-1?1:0;' o2 M, b9 V8 w% l7 H. W( l6 M, O
}}
  V) W+ ~% \- W" v1 F4 `$ e$ j6 L2 M7 H9 P5 x
" [" T1 |2 W% f5 S' o, e9 F7 ?
2 K% B8 {% ^9 ~6 o! U% y
函数模板使用示例:3 t' q- N9 m# w; U
在以上那段代码的后面加上以下代码:
  S0 }- f7 |$ j0 K( N8 j
2 Q4 W* v* i2 C1 G " X8 ]) E2 w/ ^% k* Y  V

: J7 p7 d0 J3 B2 E' |" z1 C- ?程序代码:
9 t: Q. g. D+ m" U9 k
0 s5 H; o, ?5 q) D1 b2 m0 p#include<strstream>8 B: |% E* V2 a$ F2 o# p1 K+ d
#include<iostream>* K* E; ]5 J! j" `7 v6 `  r
#include<string>7 _0 Q: Z2 t2 j$ [7 _
using namespace std;
6 S& @0 M5 [% J( S4 ]& ?- pint main(void)6 r' A5 w5 {  D
{
# d# S' b7 D+ J    string s1;
! P# \6 L# Y1 V; a# o# m    while(cin>>s1)
6 i, {: R' c. d+ r    {
: Y3 `. @% H  u9 h        istrstream isin(s1.data());/ f  s: z9 A+ `! U' @
        double d;
7 T0 s# `6 a5 _6 J% ^2 I        if(fy_Exp::GetExpValue(isin, d))1 V; d  R3 q  z- O& E
        {
6 w9 ]: K( ~1 F8 r0 z) w            cout<<d<<endl;
" M8 e; |! H4 M0 u" `! w        }! a; z8 v2 V; a6 o
        else5 c% W8 R  U! P/ M: i; m$ `* [
        {3 g: n! j  G* t, l% Q* Q
            cout<<"ERROR"<<endl;$ [" v$ Q/ b* z) v5 Z' X
        }
1 y& P9 d4 r( F6 M# f/ v- t) F6 c    }
8 @4 x! A! e3 v- h1 ?2 i    return 0;/ D- t( \4 t+ K8 ?% \
}- Y. l9 M$ u0 u8 ~4 l3 P! u/ j

; b8 a! a  s3 z2 B, N  |) e0 c
, B" ]9 M% K9 p( S2 |3 M然后编译执行就可以了(*^_^*)
0 f. U  f; x% g% b$ b其它:TC++上一定编译错误,不保证在VC6上也能通过编译
  ^( L1 W8 W& C+ {4 w1 w* c$ o      建议使用VC7或VC更高版本,或者使用GNU C++编译

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