一个简单的识别函数的计算器

原创 2004年10月27日 22:35:00

可以支持简单的函数计算:如(+、-、*、/、^、sin, cos)等等。
用正则表达式写的,核心就如下了:

// compute.h

//

#ifndef HEADFILE_COMPUTE_H_H

#define HEADFILE_COMPUTE_H_H

 

#pragma once

 

class CCompute

{

public:

    CCompute(FILE* fp);

    ~CCompute();

    void Compute();

 

private:

    void match(char expectedToken);

    void error();

    void delSpace();

 

    const double term();

    const double exp();

    const double factor();

    const double power();

    const double KeyWordOperator();

    const double KeyExp();

 

    const CString GetOperatorName();

 

    bool IsAccepted(char);

    bool IsLegal(char) const;

 

public:

    bool m_bError;

    CString m_cResult;

    CString m_strExpress;

 

private:

    FILE* m_fp;

    char m_cToken;

};

 

#endif

 

// compute.h

//

#include "StdAfx.h"

#include "Compute.h"

 

/** 表达式

  * <exp> -> <term> {<addop> <term>}

  * <addop> -> + | -

  * <term> -> <factor> {<mulop> <factor>}

  * <mulop> -> * | /

  * <factor> -> <power> {<powop> <power>}

  * <powop> -> ^

  * <power> -> <KeyExp> | number

  * <KeyExp> -> (exp) | KeyWordOper(exp)

  **/

 

CCompute::CCompute(FILE* fp)

{

    m_fp = fp;

    m_cToken = ' ';

    m_cResult = "";

    m_bError = false;

    m_strExpress = "";

}

 

CCompute::~CCompute()

{

    m_fp = NULL;

}

 

void CCompute::error()

{

    m_bError = true;

}

 

void CCompute::match(char expectedToken)

{

    if(m_cToken == expectedToken)

    {

        m_cToken = getc(m_fp);

        m_strExpress += expectedToken;

    }

    else

        error();

}

 

const double CCompute::exp()

{

    double temp;

    delSpace();

    temp = term();

    delSpace();

    while((m_cToken == '+') || (m_cToken == '-'))

    {

        switch(m_cToken)

        {

        case '+' :

            match('+');

            delSpace();

            temp += term();

            delSpace();

            break;

        case '-':

            match('-');

            delSpace();

            temp -= term();

            delSpace();

            break;

        default:

            break;

        }

    }

    return temp;

}

 

const double CCompute::term()

{

    double t;

    delSpace();

    double temp = factor();

    delSpace();

    while((m_cToken == '*') || (m_cToken == '/'))

    {

        switch(m_cToken)

        {

        case '*':

            match('*');

            delSpace();

            temp *= factor();

            delSpace();

            break;

        case '/':

            match('/');

            delSpace();

            t = factor();

            if(t != 0.0)

                temp /= t;

            else

                error();

 

            delSpace();

            break;

        default:

            delSpace();

            break;

        }

    }

    return temp;

}

 

const double CCompute::factor()

{

    delSpace();

    double temp = power();

    delSpace();

    while(m_cToken == '^')

    {

        match('^');

        delSpace();

        temp = pow(temp, power());

        delSpace();

    }

    return temp;

}

 

void CCompute::delSpace()

{

    if(' ' == m_cToken)

    {

        m_cToken = getc(m_fp);

        delSpace();

    }

}

 

const double CCompute::power()

{

    double temp = 0.0;

    delSpace();

   

    if(isdigit(m_cToken) || (m_cToken == '.')

        || (m_cToken == '-') || (m_cToken == '+'))

    {

        CString strTemp;

        if('-' == m_cToken)

        {

            fscanf(m_fp, "%lf", &temp);

            strTemp.Format("%0.10lf", temp);

            temp *= -1;

            m_strExpress += m_cToken + CutTail(strTemp);

           

            m_cToken = getc(m_fp);

            if(IsAccepted(m_cToken))

                delSpace();

            else

                error();

        }

        else if('+' == m_cToken)

        {

            fscanf(m_fp, "%lf", &temp);

 

            strTemp.Format("%0.10lf", temp);

            m_strExpress += m_cToken + CutTail(strTemp);

 

            m_cToken = getc(m_fp);

            if(IsAccepted(m_cToken))

                delSpace();

            else

                error();

        }

        else

        {

            ungetc(m_cToken, m_fp);

            fscanf(m_fp, "%lf", &temp);

           

            strTemp.Format("%0.10lf", temp);

            m_strExpress += CutTail(strTemp);

           

            m_cToken = getc(m_fp);

            if(IsAccepted(m_cToken))

                delSpace();

            else

                error();

        }

    }

    else

        temp = KeyExp();

   

    return temp;

}

 

void CCompute::Compute()

{

    m_cToken = getc(m_fp);

    double result = exp();

 

    if(false == m_bError)

    {

        if(m_cToken == '/n' || m_cToken == EOF)

            m_cResult.Format("%0.10lf", result);

    }

    else

        m_cResult = "Error";

    m_cResult = (m_cResult == "" ? "Error" : m_cResult);

}

 

const CString CCompute::GetOperatorName()

{

    CString _strName;

    while(IsLegal(m_cToken))

    {

        _strName += m_cToken;

        m_cToken = getc(m_fp);

    }

    _strName.MakeLower();

    m_strExpress += _strName;

 

    return _strName;

}

 

bool CCompute::IsLegal(char c) const

{

    if ((c > 0X60 && c < 0X7B)

        || (c > 0X40 && c < 0X5B)

        || (c > 0X2F && c < 0X3A)

        || (c == 0X25))

        return true;

    else

        return false;

}

 

const double CCompute::KeyWordOperator()

{

    delSpace();

    CString _strOpName = GetOperatorName();

    delSpace();

    match('(');

    delSpace();

//

    double temp = 0.0;

    double _nExp = exp();

    if(_strOpName)

    {

        if(_strOpName == "sqrt")

            temp = sqrt(_nExp);

 

        else if((_strOpName == "abs")

            || (_strOpName  == "fabs"))

            temp = fabs(_nExp);

 

        else if(_strOpName  == "sin")

            temp = sin(_nExp);

 

        else if(_strOpName  == "cos")

            temp = cos(_nExp);

 

        else if((_strOpName == "tan")

            || (_strOpName  == "tg"))

            temp = tan(_nExp);

 

        else if((_strOpName == "asin")

            || (_strOpName  == "arsin")

            || (_strOpName  == "arcsin"))

            temp = asin(_nExp);

 

        else if((_strOpName == "acos")

            || (_strOpName  == "arcos")

            || (_strOpName  == "arccos"))

            temp = acos(_nExp);

 

        else if((_strOpName == "atan")

            || (_strOpName  == "artan")

            || (_strOpName  == "arctan"))

            temp = atan(_nExp);

 

        else if((_strOpName == "lg")

            || (_strOpName  == "lge"))

            temp = log(_nExp);

 

        else if((_strOpName == "log")

            || (_strOpName  == "log10"))

            temp = log10(_nExp);

 

        else if((_strOpName == "ctan")

            || (_strOpName  == "ctg"))

            temp = 1.0 / tan(_nExp);

 

        else

            error();

    }

//

    match(')');

    delSpace();

    return temp;

}

 

const double CCompute::KeyExp()

{

    double temp = 0.0;

    delSpace();

    if(m_cToken == '(')

    {

        match('(');

        delSpace();

        temp = exp();

        delSpace();

        match(')');

    }

    else if(IsLegal(m_cToken))

        temp = KeyWordOperator();

    else

        error();

 

    return temp;

}

 

 

bool CCompute::IsAccepted(char c)

{

    return

        (

        (' ' == c) || ('+' == c) ||

        ('-' == c) || ('*' == c) ||

        ('/' == c) || ('^' == c) ||

        ('(' == c) || (')' == c) ||

        (EOF == c) || ('/n' == c)

        );

}


 

JSP+JavaBean编写一个计算器

Java: Jsp:
  • like7xiaoben
  • like7xiaoben
  • 2011年11月06日 16:41
  • 1699

JSP练习之简单计算器(使用jsp+javabean模式)

JSP案例之实现一个功能简单的计算器小程序
  • qq791967024
  • qq791967024
  • 2015年01月28日 17:57
  • 2277

JavaBean编写一个计算器

Java: Jsp:
  • WangMan_512
  • WangMan_512
  • 2011年11月07日 21:19
  • 1008

19-php函数(方法)的初步了解,简易计算器

function01.php
  • u010653050
  • u010653050
  • 2013年07月30日 18:01
  • 866

MFC实现一个简单的计算器

在VS2013环境下用MFC实现一个简单的计算器,主要是为了熟悉MFC编辑框的使用和消息传递机制。 实现步骤: 1、在工具箱托两个Edit control,一个显示可见,另一个不可见(用于保存操作数)...
  • u014164050
  • u014164050
  • 2014年12月12日 14:55
  • 1022

自己编写的一个简单的计算器

1,在android中使用GridLayout布局来编写计算器,首先了解一下GridLayout网格布局。 GridLayout网格布局   android4.0(API在14及其以上)以...
  • zhangvalue
  • zhangvalue
  • 2015年10月22日 12:13
  • 6424

MFC一个简单的计算器程序

1,简介 某个晚上帮人做的一个MFC课程设计的作业。大概花了两三个小时。 效果: 就和平常使用的计算器用法差不多。 2,源码下载 MFC一个简单的计算器程序源码 3,...
  • dpsying
  • dpsying
  • 2014年02月10日 20:54
  • 47000

一个简单的JSP+JavaBean web计算器

什么是JavaBean实际上,JavaBean就是一个Java类,只不过是一些遵循特定接口格式的Java类。为了直观地说明问题,我们直接看一个例子:Add.javapublic clas Add { ...
  • a153375250
  • a153375250
  • 2016年03月14日 12:52
  • 1946

一个基于JavaScript的简单网页计算器

一个基于JavaScript的简单网页计算器,真的很简单。 效果如下: A simple Calculator .number{ ...
  • Youyou_0826
  • Youyou_0826
  • 2017年04月20日 14:26
  • 1297

android:第一个android项目 简单计算器

以前自己写过java版的简单计算器 代码其实都一样就是改改布局 不过我现在不会获取屏幕大小。。然后按照比例设置按钮的长宽。所以先这样凑合把 都在左上角。。 像这样 我用的相对布局 感觉这样比较方便 l...
  • su20145104009
  • su20145104009
  • 2016年02月01日 16:00
  • 4102
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:一个简单的识别函数的计算器
举报原因:
原因补充:

(最多只允许输入30个字)