返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,) i% B& m1 O4 o& S6 T
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式6 O  K/ L% ~* u' ~9 j) q, k' T
只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn). W6 D! [1 O2 C( s4 r
参数解释:
9 E3 `1 c2 V# c/ K- r; \0 s* Eistrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
6 j7 t+ O  k& u" ~( OnReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
1 a2 i' ^& }& _1 }返回值:
. Q( E, e; `  m9 [5 N返回非0表示计算成功,0表示计算失败有错误
3 {* T6 {, y$ T
# W5 [, }. L! Z9 D5 J- {0 _' [ " a5 f# g7 ^9 Y* L: j9 a( Z
/ B( w; ~. o* D: D7 X: B
程序代码: 3 T; H, \) v4 k( t) |4 j' L$ T3 Y

2 G2 Q- D8 O5 g3 W# Ynamespace fy_Exp{1 N! |/ W" H- }
namespace {template <class _T>/ l+ Q7 n0 n( W2 z1 |& D3 G% h. \
inline _T GetExpValue(_T t[], char& csym){: B. Y! b2 N- Q- a" p+ A+ ?0 q% r
    char c=csym; csym=0;
% h* T9 r' [+ W: h8 S& L5 n$ n: m2 s    switch(c){- S% m3 E' N- r9 `  b" v2 {
    case '+':return t[0] += t[1];& P4 A# W5 ]/ ^6 d* z
    case '-':return t[0] -= t[1];0 d6 {! j$ Q! X# M9 M
    case '*':return t[0] *= t[1];
5 F% R, E6 t; f. u3 V    default: return t[0] /= t[1];//case '/':
& z  K' E8 ]8 q, t' n* t! X    }( k* n3 E! L* y0 q1 E8 J0 n' [
}}+ c. V3 p# A! q' d
template <class _T, class _Tstream>$ b) U! s- ~! s9 g" y) e" E
/* _Tstream: inputstream, _T: get return value! z" N% D  d, _1 r4 q7 i) p
* Return nonzero if get value successfully */: j: Q, E( ?3 D' z1 u/ e$ t1 q
int GetExpValue(_Tstream& istrin, _T& nReturn){6 f% w, F$ `! f' M: y% Y, ^0 k' \
    _T t[3] = {0}; //雨中飞燕之作
; b% p. m* E: _8 L' W- ^1 i& `    char csym[3] = "++";) C1 I* ~6 c# m+ [0 t- a
    int nLevel = 1, nERR = 0;
  @0 @" d: V: ~/ Q    if(!(istrin>>t[1]))istrin.clear();2 E  A, m+ E; S9 n" z
    for(;;){
0 v# p: B6 H9 r0 q6 q4 y4 h        if(istrin>>csym[2]){
8 U3 ^: n: a8 a  ]1 ~: h( V            switch(csym[2]){/ R% ?; D+ u  m0 c
            case '(':0 k2 b# @2 k6 ^1 ]
                if(!csym[1]){nLevel=0x100; nERR=1;}else
  p- V7 J7 i/ h9 i1 K2 K0 C                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;" z5 y. p1 U% w! G9 D! g$ P
                else{nLevel=0x100; nERR=1;}) R' ^; Y: |% S
                break;1 H' m, ^$ ^, n% Q8 [
            case ')':
, A  c' V* C9 G( ^" A# \                {nLevel = 0x100;}break;* v% l, E8 N& x& _; z
            case '+':case '-':case '*':case '/':
! D" G, c- l  p$ E8 H                {csym[nLevel++] = csym[2];}break;5 E2 V4 K! N" `& ~; m- _
            case ' ':case '\r':case '\n':case '\t':continue;. l. L% ^6 p4 b$ Z& K& r; u/ p
            default:# g! [* r/ G4 I8 k
                {nLevel=0x100; nERR=1;}
2 M5 M% E0 r% v4 o* I            }1 k7 b. H# D9 }$ V  O8 x- b5 Z
            if(nLevel==0x100)break;: G3 Q2 }+ U4 y9 Z/ S; y
            if(nLevel&0x10 || istrin>>t[2]){
" i. x$ f* [% M6 \* B2 x0 ^                nLevel &= 0xF;
5 L. y: P$ N, ^: S9 b9 z) f                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
6 p/ {9 ?% r/ J% O5 f3 b, B, m' A5 W                if(csym[1]=='*'||csym[1]=='/'){- }6 ?# X" d, d. g9 ?( Q+ d
                    GetExpValue(t+1, csym[1]);
1 t  M& C# g" {# @                }
  F) K; ^6 Z) }4 P. r                else{  r+ l8 G5 J8 {2 c
                    GetExpValue(t, csym[0]);: O& `0 }5 y3 R6 `* j8 A. T' w: E$ |
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;8 z; N5 B4 f; z' z6 b! j, Y
                }
+ C6 v" M! N3 n  `                nLevel = 1;
* C! |" e& A# J& q5 s# C& q            }1 Q) f8 d2 Y/ I0 r4 y
            else istrin.clear();
$ g6 A, @5 |% V5 t" L        }, _" |0 A1 N/ `2 `+ _1 C3 ^0 o
        else{nERR = -1; break;}
1 b1 v8 V' U  I+ A2 J6 u    }
( y9 ^, H7 C% m% M: E# {    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);4 \8 R- Q+ v& m: `
    else nReturn=GetExpValue(t, csym[0]);) A, w2 K# o+ F) T" a) y
    return nERR==-1?1:0;
7 H9 ~4 P( J8 e( g# ]: k" H& A}}
9 c* |1 q" V: \0 t" p5 u2 D
8 V, A9 o; u% x% W' m- m. @) x7 c* l2 u% ^" B

/ v4 y$ i  J: G* d- Y- N函数模板使用示例:6 W- `' j5 a5 L0 P
在以上那段代码的后面加上以下代码:
3 O; Q/ q2 B5 N
9 }- h6 ^8 A3 [: b9 F
7 |* ]9 L) x7 j! a9 s* |2 G
' U; `, d9 I: T  B: N程序代码: 3 M8 j5 l! a2 }0 \+ k4 s& A& Y1 v
% u/ A/ h* b/ G7 ~1 L
#include<strstream>
' H5 w! ?: r% Q, w& U0 I! j#include<iostream>
) N  @/ s7 W- m7 j#include<string>
9 X- K3 t# ^1 Dusing namespace std;: h3 I7 ?6 I1 S; P/ S( E
int main(void)
% X/ V3 F* t1 `4 r4 y& Q( [{  C5 `, A6 X7 o" p: \
    string s1;9 B! m* h  \+ d2 n6 Q# d/ y$ P% S
    while(cin>>s1)4 N2 R5 F. b# ~- E" g
    {0 ~6 C9 \, z8 V0 ?) E; y* J. c
        istrstream isin(s1.data());
" o' Y2 m1 j% N$ ]4 w* U        double d;1 q9 |! W3 t2 b$ I3 k8 C
        if(fy_Exp::GetExpValue(isin, d))" v. j3 H# \, a4 g' `/ _
        {
" C  L: `$ Q2 J6 E            cout<<d<<endl;
% g+ ]) I9 n( s8 o6 Y6 c; G! }; n        }( ^0 C: T$ s) T$ R  p
        else2 U; k6 g  l' N% H9 x8 H. Q
        {1 c& A+ o6 j4 ]6 d1 T
            cout<<"ERROR"<<endl;1 W7 o, S3 W5 b/ g$ |3 R3 t! T8 y5 a1 ^
        }
/ Q8 P( \% _) j; O; b    }
+ Y6 i+ U: v& _/ C9 c    return 0;
" v5 _+ f0 \& }" X! g' M$ u9 Y}( W8 W8 }+ y9 F/ f4 S# T

# Y$ D- c% t& ?: Z: B( W6 `+ ^1 V) s
4 x8 l5 P2 K+ [8 s# s0 _3 t0 S  u然后编译执行就可以了(*^_^*)
3 z$ i- M5 q8 |其它:TC++上一定编译错误,不保证在VC6上也能通过编译
" T8 v* q6 H& o  s8 C& K      建议使用VC7或VC更高版本,或者使用GNU C++编译

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