分享
 
 
 

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

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

可以支持简单的函数计算:如(+、-、*、/、^、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)

);

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有