计算包含函数的算术表达式

       算术表达式可以使用中缀表达式和后缀表达式(逆波兰表达式)计算,以下分别实现这两个方法,以下实现方法可以在算术表达式中包含部分函数,如三角函数sin等。

        由于普通的算术操作符(如“+-*/”)只包含一个字符,而函数会包含多个字符,为了方便先将函数用一个FunctionId的枚举替代,该枚举从1开始,算术表达式一般为明文字符串,这些枚举数只要使用20以下的数字就不会发生冲突,只是打印出来会是乱码,计算不会受影响。

enum FunctionId
{
	None = 0,
	Sin = 1,
	Cos = 2,
	Tan = 3,
	Cot = 4,
	FunctionMax,
};

         然后定义函数和运算符的结构FunctionInfo和OperatorInfo,以及一些全局变量和方法。


struct FunctionInfo
{
	FunctionId funcId;
	char funcStr[10];//函数名,如"sin"
	int bytesOfStr;//函数名字节数,如"sin"为3字节
	FunctionInfo(FunctionId InFuncId, const char* InFuncStr, int InBytes = 0)
	{
		funcId = InFuncId;
		memset(funcStr, 0, 10);
		bytesOfStr = InBytes > 0 ? InBytes : strlen(InFuncStr);
		memcpy(funcStr, InFuncStr, bytesOfStr);
	}
	static FunctionInfo None;
};
FunctionInfo FunctionInfo::None = FunctionInfo(FunctionId::None, "", 0);

FunctionInfo g_functionInfos[] =
{
	FunctionInfo(FunctionId::Sin,   "sin",   3),
	FunctionInfo(FunctionId::Cos,   "cos",  3),
	FunctionInfo(FunctionId::Tan,   "tan", 3),
	FunctionInfo(FunctionId::Cot,   "cot", 3),
	FunctionInfo::None
};
//判断是否是函数
FunctionInfo GetFunctionInfo(const char* InExp)
{
	for (int i = 0; i < FunctionId::FunctionMax; i++)
	{
		if (g_functionInfos->funcId == FunctionId::None)
		{
			return FunctionInfo::None;
		}
		if (memcmp(InExp, g_functionInfos[i].funcStr, g_functionInfos[i].bytesOfStr) == 0)
		{
			return g_functionInfos[i];
		}
	}
	return FunctionInfo::None;
}

struct OperatorInfo
{
	char ch;//运算符
	int priority;//优先级
	OperatorInfo(char InChar, int InPriority)
	{
		ch = InChar;
		priority = InPriority;
	}
};
OperatorInfo g_operatorInfos[] =
{
	OperatorInfo('(',   0),
	OperatorInfo(')',   0),
	OperatorInfo('+',   1),
	OperatorInfo('-',   1),
	OperatorInfo('*',   2),
	OperatorInfo('/',   2),
	OperatorInfo('%',   2),
	OperatorInfo('^',   3),
	OperatorInfo('\0',  -1)
};
//判断是否为操作符
bool IsOperator(char c)
{
	for (int i = 0;; i++)
	{
		if (g_operatorInfos[i].ch 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值