C++表达式计算类示例

// 程序基于C++之父的表达式计算例子改版为字符串流计算
#ifndef __EXPR__CALC__H__
#define __EXPR__CALC__H__

#include <iostream>
#include <map>
#include <string>
#include <sstream>

enum Token_value
{
	NAME,       NUMBER,      END,
	PLUS='+',   MINUS='-',   MUL='*', DIV='/',
	PRINT=';',  ASSIGN='=',  LP='(',RP=')'
};

class ExprCalc
{
public:
	ExprCalc() : curr_tok(PRINT),no_of_errors(0) {}

	~ExprCalc()	{ ss.clear(); table.clear(); }

	void operator << (const std::string &exp);

	void set(const std::string &var, double val);

	void set_table(std::map<std::string,double> &tab);

	double calc();

	bool get_error();

private:

	Token_value get_token();

	double term(bool get);

	double expr(bool get);

	double prim(bool get);

	double error(const std::string& s);
	
private:
	std::map<std::string,double> table;
	std::stringstream ss;	
	std::string string_value;
	double number_value;
	int no_of_errors;
	Token_value curr_tok;
};


#endif 


#include "stdafx.h"
#include "ExprCalc.h"

Token_value ExprCalc::get_token()
{
	char ch;
	do{
		if(!ss.get(ch))return curr_tok = END;
	}while(ch!='\n' && isspace(ch));

	switch(ch)
	{
	case ';':
	case '\n':
		return curr_tok = PRINT;

	case '+':
	case '-':
	case '*':
	case '/':
	case '(':
	case ')':
	case '=':
		return  curr_tok = Token_value(ch);

	case '0':case '1':case '2':case '3':case '4':
	case '5':case '6':case '7':case '8':case '9':
	case '.':
		ss.putback(ch);
		ss>>number_value;
		return curr_tok = NUMBER;

	default:
		if(isalpha(ch))
		{
			string_value = ch;
			while(ss.get(ch) && isalnum(ch))string_value.push_back(ch);
			ss.putback(ch);
			return curr_tok = NAME;
		}
		error("非法变量名");
		return curr_tok = PRINT;
	}
}

double ExprCalc::term(bool get)
{
	double left = prim(get);
	for(;;)
	{
		switch(curr_tok)
		{
		case MUL:
			left *= prim(true);
			break;
		case DIV:
			if(double d = prim(true))
			{
				left /= d;
				break;
			}
			return error("除以0溢出");

		default:
			return left;
		}
	}
}

double ExprCalc::expr(bool get)
{
	double left = term(get);

	for(;;)
	{
		switch(curr_tok)
		{
		case PLUS:
			left += term(true);
			break;
		case MINUS:
			left -= term(true);
			break;
		default:
			return left;
		}
	}
}

double ExprCalc::prim(bool get)
{
	if(get)get_token();

	switch(curr_tok)
	{
	case NUMBER:{
		double v = number_value;
		get_token();
		return v;
				}

	case NAME:  {
		if(table.find(string_value) == table.end()){no_of_errors++;}
		double& v = table[string_value];
		if(get_token() == ASSIGN){v = expr(true);}
		return v;
				}

	case MINUS: {return -prim(true);}

	case LP:    {
		double e = expr(true);
		if(curr_tok != RP){return error("没有匹配右括号");}
		get_token();
		return e;
				}
	default:
		return error("初等项异常");
	}
}

double ExprCalc::error(const std::string& s)
{
	no_of_errors++;
	printf("错误: %s \n", s.c_str());
	return 1;
}

double ExprCalc::calc()
{
	no_of_errors = 0;
	double ret = 0;
	while(!ss.eof())
	{
		get_token();
		if(curr_tok == END)break;
		if(curr_tok == PRINT)continue;

		ret = expr(false);		
	}
	ss.clear();
	return ret;
}

void ExprCalc::set(const std::string &var, double val)
{
	if(table.find(var)!=table.end())
	{
		table.erase(var);
	}

	table[var] = val;
}

void ExprCalc::operator << (const std::string &exp)
{
	ss.clear();
	ss << exp;
}

void ExprCalc::set_table(std::map<std::string,double> &tab)
{
	table.clear();
	table.swap(tab);
}

bool ExprCalc::get_error()
{
	return (no_of_errors != 0);
}

#include "ExprCalc.h"

int main(int argc, char *argv[])
{
	ExprCalc ec;
	ec.set("a2",3);
	ec.set("b3",2.5);

	ec<<("a2*100 /b3");
	printf("%lf\n",ec.calc());

	ec<<(" a2 * ( b3 + 1 / 3 )");
	printf("%lf\n",ec.calc());
	
	ec.set("a2",4);
	ec<<("a2 * (b3 +1 /3) -1/3");
	printf("%lf\n",ec.calc());

	return 0;
}


C++ lambda 表达式的语法如下: ``` [capture](parameters) -> return_type { body } ``` 其中: - `capture`:捕获列表,用于指定 lambda 表达式内部可访问的外部变量。捕获列表可以为空,也可以使用`[]`、`[=]`、`[&]`等形式进行指定。 - `[]`:不捕获任何外部变量。 - `[=]`:以值方式捕获所有外部变量。 - `[&]`:以引用方式捕获所有外部变量。 - `[var]`:以值方式捕获变量 `var`。 - `[&var]`:以引用方式捕获变量 `var`。 - `parameters`:参数列表,用于指定 lambda 表达式的参数。 - `return_type`:返回型,用于指定 lambda 表达式的返回型。可以省略,编译器会自动推导。 - `body`:函数体,用于实现 lambda 表达式的逻辑。 下面是一个 lambda 表达式示例: ```cpp #include <iostream> int main() { int x = 5; int y = 10; // Lambda 表达式捕获外部变量 x,并接受一个参数 a auto lambda = [x](int a) { return x + a; }; int result = lambda(y); std::cout << "Result: " << result << std::endl; // 输出: 15 return 0; } ``` 在上面的示例中,lambda 表达式 `[x](int a) { return x + a; }` 捕获了外部变量 `x`,并接受一个参数 `a`。在 lambda 表达式内部,它实现了将 `x` 和 `a` 相加的逻辑,然后通过调用 `lambda(y)` 来计算结果,最后将结果输出到控制台。 请注意,由于 lambda 表达式的返回型可以自动推导,所以在这个示例中我们没有显式指定返回型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值