返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
/ o; T# V  q* M: P( Q7 Y% e2 m一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
0 k- U* ]1 m; Q8 S7 D) M! O只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)% x. I* C! g" u" t% A& h$ g
参数解释:* l5 x7 |7 z) I
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
. u- D2 q4 ?. _* u$ j! ?nReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定! b5 g  ]* V7 b! [1 F
返回值:+ l5 h6 U: s% ~, Y8 F7 @5 ?( x/ m
返回非0表示计算成功,0表示计算失败有错误
7 D( I  D( L  K' N( P" U1 W4 f# P2 Q4 x+ R

3 Q$ j" u# S, G( p3 M5 j+ a; L% c6 P- S
程序代码: " b. s4 c" }& C, Y

1 q' C4 ~' ?: v* |9 r- F( Ynamespace fy_Exp{
8 }: @$ j( v) nnamespace {template <class _T>+ |  R6 q- ^6 y! o' A3 N/ b
inline _T GetExpValue(_T t[], char& csym){
, t5 N8 h" H0 t    char c=csym; csym=0;
. _: u4 r6 y7 b. y* ?6 f$ U4 i    switch(c){. m; ^* R5 y' U) J; D: S, G/ H
    case '+':return t[0] += t[1];$ z# H5 r1 h3 S1 T
    case '-':return t[0] -= t[1];
" N! ~3 X# t5 Z! z% A8 P( A    case '*':return t[0] *= t[1];- Z- x9 u+ ~, b/ [9 B! i( U
    default: return t[0] /= t[1];//case '/':
' ?& z) n; e7 a: ]' @" h    }
8 [& K' Q- |/ Z, D0 y}}* D( a9 s) m  M) D1 U
template <class _T, class _Tstream>
, K# ]! q, U9 `$ G" n' m; }' X% }/* _Tstream: inputstream, _T: get return value+ [# x( L6 {. F# G% s. G$ K
* Return nonzero if get value successfully */
) R; y4 Q' m4 Tint GetExpValue(_Tstream& istrin, _T& nReturn){
  u$ ^' f7 ]- a5 G; r) t/ w    _T t[3] = {0}; //雨中飞燕之作
0 @: F' x! ]1 a7 v4 f8 R6 N# @    char csym[3] = "++";' Z# _/ H% Y# |% A, K* _: V1 m5 e
    int nLevel = 1, nERR = 0;
3 X8 R3 b' ]: Y3 Y/ z6 L    if(!(istrin>>t[1]))istrin.clear();
7 d! _. k/ {$ N& f8 R5 h" H    for(;;){
2 }4 [, t; M6 A3 X        if(istrin>>csym[2]){
9 \8 t5 v, Y1 U& E* t            switch(csym[2]){" V' \6 E" w1 o1 ?9 P' S& }9 u
            case '(':, l! }7 u: M! O1 ~0 l& R
                if(!csym[1]){nLevel=0x100; nERR=1;}else$ t! T. X- N2 ^3 |
                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;* Y7 D/ v9 O; U# e
                else{nLevel=0x100; nERR=1;}
1 o+ k1 x3 b; L$ S8 P# r                break;
3 Q- s2 \' v1 q2 D3 z" D$ U& ~            case ')':
* V9 j1 h' D$ V/ `& S% m                {nLevel = 0x100;}break;- s- Q1 `* t; [
            case '+':case '-':case '*':case '/':. T5 T- K  F' T/ n/ u7 T
                {csym[nLevel++] = csym[2];}break;
$ y3 Q2 l7 H" P$ B5 v' W8 O            case ' ':case '\r':case '\n':case '\t':continue;8 J! v8 _" \. k
            default:+ O9 X& S3 Z( @3 R5 P& T/ D
                {nLevel=0x100; nERR=1;}3 }4 r2 ?1 A4 G; a
            }
2 V3 n. ~6 L! D            if(nLevel==0x100)break;
% ^2 c  O$ @2 E, }; F            if(nLevel&0x10 || istrin>>t[2]){6 Q( b3 B9 D8 r9 z! P$ g0 S0 k
                nLevel &= 0xF;' G/ q' q+ o  a3 F6 b+ ]
                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}& G7 r7 }' F! ], f& l2 u
                if(csym[1]=='*'||csym[1]=='/'){
- s& r' Y9 I1 Z9 c5 X. P                    GetExpValue(t+1, csym[1]);
9 y5 D. y1 x% w6 ^. L8 d                }; U. W/ z6 A( f7 y; `
                else{. @& F. Z( b2 {
                    GetExpValue(t, csym[0]);' |0 p6 n0 V/ X7 b. N5 w. }) S( N8 c
                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;  h" v& G  o  R. S( g! C. C' z
                }
) e7 _2 B# S% w% R                nLevel = 1;
6 J% e/ n6 T  M& f& T+ }7 W            }
2 I3 P7 u0 [3 K5 p% h8 f2 E            else istrin.clear();' u$ B. F& ]1 \& W* y
        }$ ^( A$ L# K3 k
        else{nERR = -1; break;}* R5 D& C" v: @' D- Y9 t! y* @
    }
2 O$ c0 _% }0 u$ E( g    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);% q- R5 q; O' j+ t: v! b
    else nReturn=GetExpValue(t, csym[0]);0 _8 z/ k5 e) V: E/ m1 [; d
    return nERR==-1?1:0;" @* _( V; \: {" h* @0 S
}}+ t& `( z; F; O$ J5 P: A

. L& x. I3 q- d4 A: k. k' ]2 `, L7 Z! g$ [0 {+ Z
1 G3 y; V" X; f6 A# V5 y, Z' f
函数模板使用示例:
% i+ E- o2 J8 n' S/ u6 `5 I( s4 L在以上那段代码的后面加上以下代码:- T& ~8 v  `& G0 ~8 ?5 z0 z& J

, S/ U: v$ n# `- C# I9 j' x
. Z% G. Z6 H  `- L6 y4 D! y, j% K6 M
程序代码:
$ {/ `+ R7 ^1 l: ?: M3 D  V
# E" j9 T; d, \2 T#include<strstream>* d) R. ?( {; k% q, l0 o- A
#include<iostream># ^5 z7 X5 `1 g+ k! R
#include<string>- j/ `  Q9 o3 Y* |# I3 T# h* `& h
using namespace std;
- u) D" F5 L% x% u& B8 |8 e- sint main(void)
* q; l/ g2 B& d, L" ^{
+ k. E9 R3 E, q- e9 f    string s1;, v6 Y( Y, b$ U" h; v  o) ~
    while(cin>>s1)" n2 C+ ^: M* q1 {3 \& V
    {
- \1 T  h+ W; |, z) \        istrstream isin(s1.data());) s& d/ W; q  s7 L! q5 a, K
        double d;9 a8 Z. b# w8 _# V( c# ~* P
        if(fy_Exp::GetExpValue(isin, d))
' W% W+ r0 b" a! f6 z0 V7 ]        {
" F! V) I& i. [" g            cout<<d<<endl;. A" m$ N8 y/ S% ^! O# c0 l
        }. }$ @; j& J3 _9 t/ m6 v
        else; L/ A/ i! m( `) M, E
        {4 x" {* f) P& Z9 u
            cout<<"ERROR"<<endl;
8 Z/ L/ v' t1 M& R: F        }, P% r6 c- R2 x8 a' w# A
    }
: t5 C$ n8 r6 x! U    return 0;$ w6 p/ Z" Q2 Q% H
}0 q/ i- I* S9 s+ R/ u
  A) |) P4 e9 I& G% r9 V( M) x
% n% S! z0 b" W( {/ Q4 e6 N
然后编译执行就可以了(*^_^*). M* X. d* k* D" [. D! H
其它:TC++上一定编译错误,不保证在VC6上也能通过编译
; {& e0 |# E0 @3 R2 K) {      建议使用VC7或VC更高版本,或者使用GNU C++编译

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