返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,0 w& B2 }2 J' ~9 u
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
8 v/ T" r8 U( f6 Z只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)7 t% W- `! S7 s- T3 @1 w5 Z& z
参数解释:# R. m1 |& h8 A" ~" f
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
3 `: @: b* x( ^( BnReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定% [0 `' S- d0 {- ?8 g1 w" @
返回值:$ ~* @" `; w0 m9 X2 K: ^) u1 N
返回非0表示计算成功,0表示计算失败有错误
& a& ^% `% W. d+ F' e3 ]" j+ f6 O' j! U6 ^; g+ n  X' B; ?- S

9 M8 d7 _+ B6 n' _, y& E8 @! ~3 B& ?& I7 l6 {5 c, U
程序代码: ( z' F, L$ X7 `; h/ J
) H% F) D: O, A
namespace fy_Exp{
+ ~2 b. c) C' gnamespace {template <class _T># J0 Y+ W& o0 ?$ z' e) Q% r
inline _T GetExpValue(_T t[], char& csym){1 K% F, e! ?6 O0 A
    char c=csym; csym=0;
  b5 D3 a3 J9 q% k2 N$ l    switch(c){
. O; n! Q9 u& D$ V    case '+':return t[0] += t[1];# K" s0 V, l# S& @$ P
    case '-':return t[0] -= t[1];2 Z9 R( S: I+ q
    case '*':return t[0] *= t[1];7 |( _% b! A3 N8 r% a4 v- H
    default: return t[0] /= t[1];//case '/':
0 i$ x/ J3 B- m- b# v1 [* F    }
2 o4 Z2 s& W  D$ x2 b5 q. ^- e- v}}% ?3 h/ \+ p$ P1 K% u
template <class _T, class _Tstream>
" s4 A1 K+ {  O' Y/* _Tstream: inputstream, _T: get return value
" S2 t+ Z: d4 E" d7 D- V7 E* Return nonzero if get value successfully */& V  S& Z  R+ f9 f* Q
int GetExpValue(_Tstream& istrin, _T& nReturn){; G4 A! q! x8 u# w: d# @
    _T t[3] = {0}; //雨中飞燕之作
: @/ v: X1 _# o7 C: {" M    char csym[3] = "++";1 D# N3 P9 E' V3 o+ y3 @: M' ?8 g
    int nLevel = 1, nERR = 0;
. w9 m. V# R1 e5 k: r! l" V6 t    if(!(istrin>>t[1]))istrin.clear();
2 A+ z( s( d& s0 D- ]' s: i6 _7 T    for(;;){
6 {- q/ B' i- j3 H        if(istrin>>csym[2]){8 q8 e3 i1 v1 [" }1 Y
            switch(csym[2]){
8 b- I. ~6 ]* n7 O. c5 A9 P            case '(':! `4 _  z4 |0 s' v6 x
                if(!csym[1]){nLevel=0x100; nERR=1;}else
  A- v: V9 b8 n% y* ^3 g                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;/ w1 N  N( n  R' k
                else{nLevel=0x100; nERR=1;}" }( C2 @7 K( z) m/ \- p* l( n5 P$ Z
                break;
, f% c$ T( W7 D" i: @# x) R9 g. H            case ')':
0 V7 z, a2 U7 D7 x+ {1 K# J                {nLevel = 0x100;}break;, n1 m% z3 f; T9 m/ Z6 R
            case '+':case '-':case '*':case '/':
3 W( d/ D8 v7 g: L7 r7 x; `8 S6 D* Q: ]                {csym[nLevel++] = csym[2];}break;
( w5 A4 E9 w$ I" s1 ?            case ' ':case '\r':case '\n':case '\t':continue;( T& |7 a) g+ F; |
            default:4 Y1 a! n! `! x0 r' E$ k6 v. K: S; Y4 ?
                {nLevel=0x100; nERR=1;}
  I" Z5 X5 G( t* _& [: [' W            }4 D  g8 s" V+ h/ R" f$ I
            if(nLevel==0x100)break;
( Q) }& `# q8 k  P( ^) T            if(nLevel&0x10 || istrin>>t[2]){7 Q! W6 p7 a# L: Y# }% @+ Y
                nLevel &= 0xF;
4 ?: z( F. n5 j9 ]+ k7 ?/ Y                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}) ~) C1 V* b: {; p- x9 g$ S$ m
                if(csym[1]=='*'||csym[1]=='/'){
/ x4 j& s( g3 s+ }                    GetExpValue(t+1, csym[1]);4 {$ r  ?! ~# R  I2 `: T
                }
2 b( A! p" T2 D2 B- S* A! I                else{4 Z8 }3 ~( v7 Y7 V4 z" N
                    GetExpValue(t, csym[0]);
! Z6 Q3 W( g& M; w. b7 O9 o                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
+ W4 x1 W( `9 r  W9 X" M9 M2 u                }6 p. I. _* k: A3 G; w
                nLevel = 1;
0 i' J5 Q0 Z8 p+ b* K9 z' u            }
! c; J- f# }7 ]- @* L( }            else istrin.clear();- u6 d8 X! d* ?3 O/ v. q
        }, L* t' w4 `) c3 i
        else{nERR = -1; break;}, \! j  B! \: u4 Z' h* Z
    }
) p8 k: k# X) }: |$ N    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);
! w# N0 B& l2 H; e  Z" ^0 b/ ]    else nReturn=GetExpValue(t, csym[0]);
& n0 h) g3 G3 o3 T3 P    return nERR==-1?1:0;
, O& Y' j& @$ S, a1 w}}0 N) Q3 n! C$ R/ Y) f# J
5 a& J$ g% N7 L% r2 e

% y: t' [/ j1 H2 s# N/ B8 N- G. N! @$ \, o  U, G  v% p
函数模板使用示例:% A& |4 s+ w0 Z, T3 P: D0 v3 J8 M
在以上那段代码的后面加上以下代码:' g/ l2 f& n# _' F5 ~) M( j

# F* ^  W/ Y! B$ T& L , D1 h4 R' V$ F% N& r
' w5 T- U% H: ]  S
程序代码:
0 C+ n$ }: O0 \, r# a! D
1 U5 A$ h9 M1 c0 P( K; B#include<strstream>
5 M& @. c. R$ B/ u, K#include<iostream>
' n) m0 ~9 e8 K0 S* n#include<string>2 d/ f8 v8 d) M8 ]7 S
using namespace std;! l+ H/ G8 ^1 e0 ~4 ]' P% v
int main(void)
8 D  L' }5 v# z; k, t8 H{
* M5 X( z0 Y( x: X, G2 x    string s1;/ W! j* `; Q0 o; z3 R5 a
    while(cin>>s1)
. i3 p4 E3 N' R9 ]3 M! r9 J, O    {
$ `7 E4 G5 F7 x+ W        istrstream isin(s1.data());
, C8 E2 b! x' G: o. b) `        double d;$ T" J' {$ U' K2 p' v
        if(fy_Exp::GetExpValue(isin, d))
8 b4 L& C9 e- a* f- H9 s        {
1 t" K' v  Q0 W+ s3 b1 W  G            cout<<d<<endl;
. e- Y2 |  B1 r# B        }
( M9 `- @! E& e- b$ t  I1 Y) l        else
' h9 _* g" O: V0 H3 S6 g' ?- x6 P        {
/ [: {8 z- _1 j: `9 |+ r            cout<<"ERROR"<<endl;
$ n8 W2 Y. v  @) `" i) a% H4 E        }) |0 P! x, Q2 v9 l. H, V4 ^# e% L
    }1 t* M% ^6 i6 f0 O1 h" E
    return 0;3 H7 G9 H$ W- n; z. X
}
. G. Z& s& y+ f! U- ?. G1 i1 G7 T& [; e1 ^7 p
" n2 U+ T+ i$ t# d- I; O
然后编译执行就可以了(*^_^*)
2 T+ y" U$ I. x" @其它:TC++上一定编译错误,不保证在VC6上也能通过编译
. o& f' w% b! t6 l; y- c. \: e      建议使用VC7或VC更高版本,或者使用GNU C++编译

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