返回列表 发帖

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

在9月8日那天我特意编写的,给大家分享的,
$ H, E* D3 e& j一个很方便的函数模板,可以并且只可以计算含括号的四则表达式
9 u5 W; A0 g( m; C" P2 G只有一个函数接口:int GetExpValue(_Tstream& istrin, _T& nReturn)
. x' @- e" w7 z/ K( U( P参数解释:3 `4 g: C9 c- q7 t! }' K
istrin: 一个输入流,可以是标准IO流,可以是文件流,也可以是串流
) L* B7 C1 c1 l3 InReturn:用于接收计算结果的变量,计算所使用的类型由这个变量确定
# Y  S8 R$ n8 j& N返回值:
7 w1 b8 u( S0 P. s返回非0表示计算成功,0表示计算失败有错误4 w8 b' O  o9 E8 i
( |( X8 g  l; M! m
* ?* U" U. h# }$ {

5 z! B3 m+ T0 x. Z2 v# f程序代码: . X- Y( C: F# k: [/ ], D4 t8 _8 U
/ f1 K  N& l) W8 d4 D6 n
namespace fy_Exp{. e# T$ a/ \2 \2 \' k& S
namespace {template <class _T>
( I5 d: f2 ^+ g* d: w! Hinline _T GetExpValue(_T t[], char& csym){
0 ~! ^; L* Y! O' m  w% U    char c=csym; csym=0;, |4 u7 E  Q" H
    switch(c){
* B% F1 f6 H1 ?4 k2 t& x    case '+':return t[0] += t[1];
( c) D) K$ w0 ~; B. p: q0 m    case '-':return t[0] -= t[1];4 z* {4 m* X3 N$ ^$ \
    case '*':return t[0] *= t[1];
# Y( u$ ~; e( `( ~' p2 Y    default: return t[0] /= t[1];//case '/':, K5 Y& {" e! b9 t. ~9 E( p
    }
1 B# d2 t2 J% w}}% x& O4 c" |0 q
template <class _T, class _Tstream>
  `, G. f8 C7 w; L1 ^( c/* _Tstream: inputstream, _T: get return value
3 P) Z: z4 N7 x/ v7 H* Return nonzero if get value successfully */& f0 U3 ]3 p& T! n
int GetExpValue(_Tstream& istrin, _T& nReturn){" R2 A% r- W- F1 I$ r% X' y; G
    _T t[3] = {0}; //雨中飞燕之作
/ T- ?0 O4 }( ^4 G/ q0 `8 a, k    char csym[3] = "++";1 Y7 G$ e7 U" d
    int nLevel = 1, nERR = 0;
4 V8 v7 c+ s& k3 O+ A% {9 i! R    if(!(istrin>>t[1]))istrin.clear();
4 l4 {: p/ U  s. m7 {$ D5 {4 ]0 U( E    for(;;){
- a; I$ J, k& U" r5 l2 H        if(istrin>>csym[2]){
- w- J7 P4 J: T9 m& m9 Z) E            switch(csym[2]){
- D( o2 j1 I" U1 [3 _2 G, n            case '(':
6 ?) a  E8 @% L! Y) I/ w, d                if(!csym[1]){nLevel=0x100; nERR=1;}else
3 V* ?! d! m1 V& ?- W9 p                if(!GetExpValue(istrin, t[2]))nLevel|=0x10;' i; ]- d3 ^. i1 N" B5 X3 e, M0 F, c
                else{nLevel=0x100; nERR=1;}
' \9 g" l& k7 ?8 W* D& i                break;
: z: A, j, x  m+ t- \  C            case ')':6 r0 \6 L1 v1 e9 Z, {; r
                {nLevel = 0x100;}break;8 h" x0 k5 n' z3 z
            case '+':case '-':case '*':case '/':
* ?, v) R) o4 w3 S3 F# B                {csym[nLevel++] = csym[2];}break;" _$ ~) J" N0 ?9 l' H
            case ' ':case '\r':case '\n':case '\t':continue;
6 y# w9 o1 E7 Z            default:. J, _0 D9 M- p# K
                {nLevel=0x100; nERR=1;}
; _/ O, T" V" _+ ~/ }1 p" }            }+ {& M- Y3 l+ c
            if(nLevel==0x100)break;
: O2 Z- G. U* I( E$ m3 O' j            if(nLevel&0x10 || istrin>>t[2]){
6 `8 a3 ^# t  ~' o9 I: A                nLevel &= 0xF;
- y, }$ L. N1 H                if(nLevel==1){t[1]=t[2];csym[1]=0;continue;}
9 Z! V4 D$ t$ p8 I$ G4 Y- M                if(csym[1]=='*'||csym[1]=='/'){
4 E$ m  E4 l" \7 c                    GetExpValue(t+1, csym[1]);2 p7 ?; }1 B# y) z/ i
                }, q" F+ ^3 @5 ~2 w' C# I  k6 _
                else{
! i/ q# t; R# J* T( D$ G5 w                    GetExpValue(t, csym[0]);
+ J# ?6 M+ Q2 Q9 {: O                    t[1]=t[2];csym[0]=csym[1];csym[1]=0;
) U4 U: Z7 h' J3 V; q! W: N2 \                }5 _- m3 z8 q; ~- E  i- E' ~
                nLevel = 1;
# y3 ~% t4 C8 j+ S+ L" Z; N            }4 T) S( P& S$ O; M
            else istrin.clear();. X, x3 t7 k# L. U
        }2 S/ @6 o' \% v2 y
        else{nERR = -1; break;}
6 f  W! w$ {1 ^1 c    }
1 i! @$ u0 s3 d+ I# P    if(csym[1])t[2]=0,nReturn=GetExpValue(t+1, csym[1]);+ |5 J" ]. u1 p: ~1 \$ C/ O- Y  }
    else nReturn=GetExpValue(t, csym[0]);5 h$ t; F0 e1 I
    return nERR==-1?1:0;" I0 Q3 W, l0 b, r" @
}}
) ]( W3 @% C, g1 _4 U
% ~; b5 z) x2 F( a# g5 Z
: Z/ V) s7 y0 V  m+ R  M
7 v+ D$ ~" M7 [$ A4 l函数模板使用示例:4 C6 }+ r5 U' b9 ]
在以上那段代码的后面加上以下代码:( V* S7 R1 N4 M4 A
5 \5 _, ^) ~& |

' N9 B( _& G8 Z' e3 M
1 k1 H" w9 j" ^程序代码:
$ \# q# ], x5 u- G: D+ f& E, Q1 P9 P2 F
#include<strstream>
1 s* I7 t' L1 h4 L  _#include<iostream>
4 v8 g1 X+ R* p" I#include<string>! C, k4 j$ e! q# m. o
using namespace std;
: }9 P" j7 ]: D! vint main(void)
& q6 y5 Z% e* s{
0 O3 |6 F( d. p! z    string s1;1 W6 h8 G! `' L& A0 _  E
    while(cin>>s1)* }5 q( T4 X+ @7 g4 m% _
    {
9 z- q' w- y/ |* t9 g/ {        istrstream isin(s1.data());4 |9 N3 P) Q2 r- v
        double d;+ g5 c: K9 N/ ~7 g" ^
        if(fy_Exp::GetExpValue(isin, d))
! b) I/ S2 O; S, N/ r( C        {
. Z" |" ?( o- s( o7 ?/ d            cout<<d<<endl;
! L  ^) K, ?; Z7 P" [8 a, u" }        }
0 h- Z" d/ h  U- \: z        else
, @5 u: G6 H# @3 |/ o        {" \, A' ^0 ~8 ], p, s
            cout<<"ERROR"<<endl;- ^( B6 z/ r# Z4 [9 F0 H: X
        }5 y- u) Y! w% w; ~
    }
( `7 V5 Y7 O6 V- z    return 0;
# M% s, K1 L  Y- J9 O# A- R}! Z! X3 m3 @1 L( m

/ d9 G6 q% W, u9 i. i) H( ~' I, {! d* o9 R
然后编译执行就可以了(*^_^*)5 D( x4 I- h0 [2 u2 o# ~- s
其它:TC++上一定编译错误,不保证在VC6上也能通过编译
# L- V; M6 g. g& p) X  U" T      建议使用VC7或VC更高版本,或者使用GNU C++编译

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