返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
  a% S8 `: Q3 \; ^( C/ W; U7 G一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
2 n" L% _9 e: N3 t1 ?) }只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
0 R% ^. |8 M; E# ?- U; Q- z参数解释:4 t/ {' p2 m- l5 S/ G2 m( U8 j: m
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流3 Y8 O/ S$ ?4 q  }, E. }8 h, q1 `
nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定! H; g1 T; \) H( z* h" ]
返回值:5 F6 W& m0 G3 p9 {
返回非0表示计算成功,0表示计算失败有错误0 f6 O$ J" Z: k5 m* g
2 y" i" a3 `( t0 l4 l. k5 w
$ K  e) B" }, K. X
6 R! i8 V( g, t; d  O
程序代码: , Z/ Z  r4 F' U4 I/ j; `

& M# C- C0 Q% Vnamespace fy_Exp{+ S: v  g7 P! F5 a
namespace {template <class _T>+ ~" R3 ~; e! _' @- [
inline _T GetExpValue(_T t[], char& csym){
+ |& y4 j( k' x# u/ [3 h    char c=csym; csym=0;& ^% y" q9 g1 j* l5 F% j
    switch(c){: b. p! x# E: E0 W7 w: o
    case '+':return t[0] += t[1];( k0 m0 W' @: R" w* X2 m
    case '-':return t[0] -= t[1];
  p9 i3 h9 h# f$ D* p; U4 }& g    case '*':return t[0] *= t[1];2 a# R9 }3 B1 _
    default: return t[0] /= t[1];//case '/':
: l% u1 G6 w. [1 M2 V& a) K    }, `3 U6 A1 ]# H
}}8 e3 Z# ^  L4 `, |
template <class _T, class _Tstream>* a  g1 |6 J1 ?/ C- `" l* K- x7 J+ O7 e( M
/* _Tstream: inputstream, _T: get return value$ K: Y' D' H' Q/ ~1 p4 q7 y9 i) f- {; f
* Return nonzero if get value successfully */
  n* J6 \& n3 W6 ?1 Qint GetExpValue(_Tstream& istrin, _T& nReturn){
$ J: V: Z7 B. `* [    _T t[3] = {0}; //雨中飞燕之作
' k8 B- {0 l# K    char csym[3] = "++";% j7 H  @6 D; M6 Y& n8 K& D
    int nLevel = 1, nERR = 0;
8 D* l' f5 R: S$ ^7 G    if(!(istrin>>t[1]))istrin.clear();! ?. M; }- {$ y  A$ Y
    for(;;){
% X' }+ X& U: P, b& c7 \        if(istrin>>csym[2]){
+ V0 ~7 f9 Y& @* s6 w4 y& n! X            switch(csym[2]){
, p8 W& R# P( Q8 g            case '(':
& |% P9 A9 |9 _  F( }  [7 M                if(!csym[1]){nLevel=0x100; nERR=1;}else
: C6 M) G6 f/ e' j8 {- e                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;
) U- I+ u) r% w$ M                else{nLevel=0x100; nERR=1;}
( L3 R- p4 u) z7 F+ S9 _                break;
( A( Q( o8 r- N- l# @8 X: ]' S            case ')':' q; q* t- b2 n! {) `9 [
                {nLevel = 0x100;}break;/ r6 j. z6 h( y/ t2 U
            case '+':case '-':case '*':case '/':
2 M- T& I4 B  H4 [$ A/ t0 c- f6 m                {csym[nLevel++] = csym[2];}break;" y6 y2 H: o" D0 f6 h/ {% p
            case ' ':case '\r':case '\n':case '\t':continue;8 y* s; y3 D6 ]; t
            default:
3 S% @8 Q5 c; v2 R                {nLevel=0x100; nERR=1;}: g! Z! d4 C" ?* o  k) J
            }
* S5 {. E6 H" H+ @2 a- q: Y            if(nLevel==0x100)break;
% p  Z: ?( R5 P' w1 b/ A8 t( A7 W5 `            if(nLevel&0x10 || istrin>>t[2]){
& I5 N- a4 ?5 [                nLevel &= 0xF;
0 V2 T0 R: c5 F                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}4 x8 m; ^/ D$ z* W- S/ f
                if(csym[1]=='*'||csym[1]=='/'){
! x0 N; r# y. X2 e                    GetExpValue(t+1, csym[1]);
3 ?/ |. Q- ^0 B4 s                }5 e* B/ C4 m- _1 B
                else{
4 g. H, l/ `) p7 I# E                    GetExpValue(t, csym[0]);2 h( h4 S0 @6 [) W* s: N
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;6 E7 |& x. [3 s  W5 K+ L& h5 {+ @
                }1 z! K8 J, W, v0 f9 Y0 ^2 k
                nLevel = 1;
5 g# Z: m; T& @5 e' z            }& I* X" ^# v( R; U$ Y$ F; C) l9 T
            else istrin.clear();
; P4 ?& K- z. S: v' F        }" J5 E* G! X) F* ^" {2 I) j5 m$ Q
        else{nERR = -1; break;}
$ u. Q, Z: M5 k    }. L# _' j7 q7 t+ p
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);; j+ B- u2 _+ h" _, j) r9 O
    else nReturn=GetExpValue(t, csym[0]);1 C9 P3 s8 J8 Z+ S& }2 y
    return nERR==-1?1:0;! W& P1 B4 H  W: a. `
}}
2 K5 |8 m3 W: C# G/ p
, Y! Y& v3 C# Z; f6 h0 R2 Y% `8 C; u' m7 m( o. J

' G% s6 L1 U% ~; B3 \+ l函数模板使用示例:
. V/ O: s! Z( M3 ~7 S在以上那段代码的后面加上以下代码:
, Y( g& K" U4 B& P, y/ S0 s# H! W) z7 N. q
& a& x- P# k- T
0 J6 \1 f2 @! u% i+ H& t
程序代码:
# c7 ~/ ]) k) A' S  F1 U$ n5 T1 K  i0 d; E8 |
#include<strstream>
9 r, R6 L: g: e8 k#include<iostream>
$ s( ~8 X& n) d0 [; C( `- k#include<string>
; i/ f- C! ~/ p( A7 Nusing namespace std;
) M9 x0 n! F2 x. B5 sint main(void)8 F" _# T; v/ s2 k4 ^
{; k& z; z( W+ N/ B2 u# |1 Q& _
    string s1;  \% ?6 e& D2 I. f+ J: o( M+ ^0 t
    while(cin>>s1); F% @! k  V0 r
    {- o. |! c* V7 T9 V% q7 L
        istrstream isin(s1.data());+ s* J1 H# O7 _& r0 V; ^; f, S
        double d;/ Y' J4 @) N) H
        if(fy_Exp::GetExpValue(isin, d))
) p& [3 e/ @2 b3 d6 C8 B, n        {
7 j- s  n! e! w/ A7 v5 f            cout<<d<<endl;& p9 P, d- n8 \6 v3 y* K
        }8 m1 [/ g# g; [# A4 c; t; C+ q
        else
  P- U8 Z4 N% p; m7 G% S# a/ O        {
& ?, o; I% B1 O& w            cout<<"ERROR"<<endl;% P$ }6 S9 f/ W; X& [+ u
        }7 m* _5 Y& I+ B0 E) R& X0 {
    }
% }0 q" k* H" |! ]1 i    return 0;
7 |; q/ @: C1 I; p}* m7 y2 }, S. S. Q
# l4 ]+ ]6 u7 e8 K5 t) Z  Q
: w( s+ ~; Y7 s, H! T) |
然后编译执行就可以了(*^_^*)2 b/ G7 G  H* @$ m
其它:TC++上一定编译错误,不保证在VC6上也能通过编译( i1 @. }5 x( x0 j1 s7 W; \
      建议使用VC7或VC更高版本,或者使用GNU C++编译

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