获得本站免费赞助空间请点这里
返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,% B- c+ H9 d* I& r. I$ B
一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
$ T7 C. s# c- s' ]7 |0 }/ C- k只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
+ |; Q6 r* W( w, f8 d+ ^* M/ M参数解释:
" H: F& L( V$ Distrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
  C4 ]" Q+ w% h$ A8 ~' d5 q: Z$ I5 |nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
2 z+ y3 }) Q5 @2 y2 z$ f$ m1 X0 F返回值:) Y1 H; i- h' c3 y+ Z! [5 E( S
返回非0表示计算成功,0表示计算失败有错误7 B' ~0 I2 G% d4 t) e# G# H0 K
4 {; V% L6 b! T0 x" s

$ t" v+ b) S/ b3 O9 H( _# `7 z
! G) a% G8 w: {$ A5 E; l程序代码:
, n' Z6 q$ U* L& K* u1 ~3 ]8 ?& J; w
namespace fy_Exp{7 ]5 [$ o1 B+ s8 q4 _" P( E: d
namespace {template <class _T>8 X- i5 i- ^; `: X
inline _T GetExpValue(_T t[], char& csym){5 E, w- ]2 G4 l6 A2 P
    char c=csym; csym=0;
1 C8 @5 t0 M+ n3 Z    switch(c){* r, B, r" j. e4 r& P% M' W
    case '+':return t[0] += t[1];; A( F+ {7 Q* s7 c, m6 Q3 y& l- @
    case '-':return t[0] -= t[1];3 X# `/ v- m7 r+ A3 W
    case '*':return t[0] *= t[1];% a. Y4 {& o, R* ^( I6 G/ S9 c
    default: return t[0] /= t[1];//case '/':
( w" y3 ^, ~' _) q# z    }) G- E! Y2 ~+ O9 u- }4 g
}}" X& f! b! i9 b6 l" O: o2 v1 }
template <class _T, class _Tstream>( u% L3 a" g. L0 p) c
/* _Tstream: inputstream, _T: get return value
# ?; P. j. p: l! f6 e5 q3 W* Return nonzero if get value successfully */* `2 |+ y# B8 Q* a
int GetExpValue(_Tstream& istrin, _T& nReturn){
  z: q' k3 ]0 t$ x- r. q7 L    _T t[3] = {0}; //雨中飞燕之作  \% l4 L3 s' H& i) h
    char csym[3] = "++";
1 K+ m. E  h& ^2 J: r    int nLevel = 1, nERR = 0;  ]) ]$ S7 F. G& z* ]0 W
    if(!(istrin>>t[1]))istrin.clear();
9 p8 ]3 u& V: ^% l: D" f4 Y    for(;;){
5 T: ^/ m, w9 `8 R- ~* m) C        if(istrin>>csym[2]){/ p2 \' E5 p; I8 e2 l' [' V8 Z
            switch(csym[2]){( t* }6 [6 i& d: `3 m: {
            case '(':
3 O' ?* v/ O3 J  |; U1 _1 e                if(!csym[1]){nLevel=0x100; nERR=1;}else$ g4 [( V  o) Z( v: i
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;) Z$ [3 N7 k$ }" W5 [1 y6 r
                else{nLevel=0x100; nERR=1;}
1 Z; }* ]2 l4 H! S) L% x5 }. X                break;
' h7 ^) t% v, I+ T            case ')':
( w% E! ]: W5 u" c5 M  x                {nLevel = 0x100;}break;
$ @* ~% J$ Y+ a% g  W0 N) g) N            case '+':case '-':case '*':case '/':
* k) h( }1 h; T: C                {csym[nLevel++] = csym[2];}break;
2 w. S" K( u" [. c: I2 M6 V; z            case ' ':case '\r':case '\n':case '\t':continue;
- l3 @$ p" F  L0 F" E            default:
' U) w' M" x6 n+ {6 Y                {nLevel=0x100; nERR=1;}
2 t3 f, U  {, ]% Y. V2 X" s7 P; O! n            }  O+ y3 E$ U# U1 Z. o( Q
            if(nLevel==0x100)break;0 j8 Y+ V/ n$ W' W' d
            if(nLevel&0x10 || istrin>>t[2]){0 ~7 @* O' W2 f) H5 K! G7 L7 ^2 y! ^9 _
                nLevel &= 0xF;
4 N( `2 k5 ~" j4 w. ~                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}" c" e$ h* @  r  x
                if(csym[1]=='*'||csym[1]=='/'){
1 E6 y8 Y9 ^" n: x; T, z1 @6 j. V                    GetExpValue(t+1, csym[1]);
8 Z4 C& s9 J1 s# q3 f                }
* S, q9 e) T/ v7 {                else{
- j! _5 A! P) j/ C* a                    GetExpValue(t, csym[0]);
0 K& D9 Q5 P, h7 I                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;/ ~9 i* z3 W  `. Y
                }
+ j- [. f2 U" r% P" F                nLevel = 1;
' k& g; ], k' F% J/ D; s) |            }
6 O) A1 Z( ^& ?; ^) b$ U            else istrin.clear();/ I/ [- w9 f1 [# r& H* v3 a
        }
0 v8 r! n, [$ M" g8 ^$ j- r1 c/ a        else{nERR = -1; break;}  c) k5 B' n" R. [; _& q
    }7 R7 r6 q; M4 h, {
    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);) H" F  s# t6 u* C9 p
    else nReturn=GetExpValue(t, csym[0]);$ R+ |! r) Q1 |
    return nERR==-1?1:0;
0 }" {" C$ L& G}}
6 m2 T" k+ O3 J/ g; z0 F7 @
7 ?3 O! w2 Z% q- ^! K& g5 ^! G/ j, ~
3 |  d: C: u8 S- [. Z
函数模板使用示例:
1 }4 n1 e! c/ m$ _8 X在以上那段代码的后面加上以下代码:
2 k3 P8 I. B  @0 i$ q
' F# _! }' I. B- y- L, ?  ~% I
6 K) m! E$ e& H# R, ^0 ~% O' n7 g& J6 r& Z# T
程序代码:   |7 I: T6 j# _2 O9 a7 Z

9 v9 H4 J+ h* a, U1 h5 H/ R1 R#include<strstream>! f8 Z- b7 Z7 a2 z& D: h! i& i6 i
#include<iostream>+ ?9 U1 Z; s$ p8 c% V, Z, u
#include<string>
2 F+ w  |* z/ Eusing namespace std;/ I9 Z1 ]3 l. f
int main(void)
' v! ^! L0 @, d: E0 y4 D  k2 E, e" q$ ^9 `{/ v0 x' P1 ?  {9 z8 S% |8 I8 z" ~
    string s1;" C# y# ]8 R" R. k+ ~! i
    while(cin>>s1)
* @' g" j" O+ e+ Y  N; h    {
  C* s9 V; s* C* a* C        istrstream isin(s1.data());
. ^2 c" f6 u0 Z9 l, |        double d;
# v, |( m* ?# l( N6 q, K        if(fy_Exp::GetExpValue(isin, d))6 h. ?1 i- V" R" e% N
        {* J7 d) J" I( y- J: w7 ]
            cout<<d<<endl;
0 N; o' z) L" a9 h  y: I  f        }
; n: |8 z! \# D- A! L6 K! J        else
2 @5 S; C$ J$ Q* J        {
* t. c# g7 r- J' X& i3 K7 W7 e  P7 C            cout<<"ERROR"<<endl;+ k, W* j% q. h! ?
        }
' [; D6 Y# a, M5 F: A, f    }; g# o% v# s; E. ~( O
    return 0;
3 N" N: S. j+ n$ N}
  N* w2 J3 e+ n8 g! ~- L4 x. G2 p" e+ Y; m1 U
/ K: v! [. F- U9 A$ Q
然后编译执行就可以了(*^_^*)
& M! a' u# X' [8 _3 x) Y其它:TC++上一定编译错误,不保证在VC6上也能通过编译
" d0 j& V8 w' R) v8 D4 v5 N! O      建议使用VC7或VC更高版本,或者使用GNU C++编译

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