CCF CSP2019.12 -- 化学方程式

CCF CSP2019.12 -- 化学方程式_第1张图片
CCF CSP2019.12 -- 化学方程式_第2张图片
CCF CSP2019.12 -- 化学方程式_第3张图片


可能在第六个测试测试点存在问题,但是很无奈,没找出来,样例数据都通过了。
个人代码如下,供参考

#include
#include
#include 
#include
#include
using namespace std;

//处理括号以及嵌套问题
void delete_brackets(map<string, int>& mp, string str, int cof) {
	deque<string> tmp_str;
	for (int i = 0; i < str.length();) {
		string tmp = "";
		tmp += str[i];
		if (str[i] >= 'A' && str[i] <= 'Z') {
			//一个大写字母后面跟着一个小写字母
			if (str[i + 1] >= 'a' && str[i + 1] <= 'z') {
				tmp += str[i + 1];
				++i;
			}
		}
		tmp_str.push_back(tmp);
		++i;
	}
	int tmp_cof = cof;
	while (!tmp_str.empty()) {
		if (tmp_str.front().c_str()[0] == '(') {
			int value = tmp_str.back().c_str()[0] - '0';
			if (value >= 2 && value <= 9) {//最后元素存在数字
				value = stoi(tmp_str.back());
				tmp_str.pop_back();  //删去数字
				if (tmp_str.back().c_str()[0] == ')') { //存在当前为“(...)num”该种形式时
					tmp_str.pop_front();  //删去左括号
					tmp_str.pop_back();  //删去右括号
					tmp_cof = tmp_cof * value;
				}
				else {//存在当前形式为“(...)element num”该种形式时
					int now_value = tmp_cof * value;
					map<string, int>::iterator iter;
					iter = mp.find(tmp_str.back());
					if (iter != mp.end())
						mp[tmp_str.back()] += now_value;
					else
						mp[tmp_str.back()] = now_value;
					tmp_str.pop_back();  //删去末尾元素
				}
			}
			else if (tmp_str.back().c_str()[0] == ')') {//最后位置不存在数字,即存在"(...)"该种形式时
				tmp_str.pop_front();  //删去左括号
				tmp_str.pop_back();  //删去右括号
			}
		}
		//存在该种"elemnet (...)..."形式时
		else if (tmp_str.front().c_str()[0] >= 'A' && tmp_str.front().c_str()[0] <= 'Z') {
			string tmp = tmp_str.front();
			tmp_str.pop_front();
			int num = tmp_cof;
			if (tmp_str.front().c_str()[0] - '0' >= 0 && tmp_str.front().c_str()[0] - '0' <= 9) {
				num = num * stoi(tmp_str.front().c_str());
				tmp_str.pop_front();//删去数字
			}
			map<string, int>::iterator iter;
			iter = mp.find(tmp);
			if (iter != mp.end())
				mp[tmp] += num;
			else
				mp[tmp] = num;
		}
	}
}

void Caculate_func(map<string, int>& mp, string str) {
	int coefficient = 1, i = 0; //系数
	if (str[i] - '0' >= 1 && str[i] - '0' <= 9) {
		string tmp = "";
		tmp += str[i];
		if (str[i + 1] - '0' >= 0 && str[i + 1] - '0' <= 9) {
			tmp += str[++i];
			if (str[i + 1] - '0' >= 0 && str[i + 1] - '0' <= 9) {
				tmp += str[++i];
			}
		}
		coefficient = stoi(tmp);
		++i;
	}
	while (i < str.length()) {
		if (str[i] >= 'A' && str[i] <= 'Z') {
			string tmp_str = "";
			tmp_str += str[i];
			if (i + 1 < str.length()) {
				//一个大写字母后面跟着一个整数
				if (str[i + 1] - '0' >= 0 && str[i + 1] - '0' <= 9) {
					string tmp = "";
					++i;
					tmp += str[i];
					if (str[i + 1] - '0' >= 0 && str[i + 1] - '0' <= 9)
						tmp += str[++i];
					map<string, int>::iterator iter;
					iter = mp.find(tmp_str);
					if (iter != mp.end())
						mp[tmp_str] += coefficient * stoi(tmp);
					else
						mp[tmp_str] = coefficient * stoi(tmp);
					++i;
				}
				//一个大写字母后面跟着一个小写字母
				else if (str[i + 1] >= 'a' && str[i + 1] <= 'z') {
					tmp_str += str[i + 1];
					i += 2;
					//判断小写字母后面是否有数字
					if (str[i] - '0' >= 0 && str[i] - '0' <= 9) {
						string tmp = "";
						tmp += str[i++];
						if (str[i] - '0' >= 0 && str[i] - '0' <= 9)
							tmp += str[i++];
						map<string, int>::iterator iter;
						iter = mp.find(tmp_str);
						if (iter != mp.end())
							mp[tmp_str] += coefficient * stoi(tmp);
						else
							mp[tmp_str] = coefficient * stoi(tmp);
					}
					//没有数字时
					else {
						map<string, int>::iterator iter;
						iter = mp.find(tmp_str);
						if (iter != mp.end())
							mp[tmp_str] += coefficient;
						else
							mp[tmp_str] = coefficient;
					}
				}
				//只有一个大写字母时
				else {
					map<string, int>::iterator iter;
					iter = mp.find(tmp_str);
					if (iter != mp.end())
						mp[tmp_str] += coefficient;
					else
						mp[tmp_str] = coefficient;
					++i;
				}
			}
			//作为最后一个原子时的判断
			else {
				map<string, int>::iterator iter;
				iter = mp.find(tmp_str);
				if (iter != mp.end())
					mp[tmp_str] += coefficient;
				else
					mp[tmp_str] = coefficient;
				++i;
			}
		}
		//遇到括号存在时
		else if (str[i] == '(') {
			int left_bracket = 0;
			int right_bracket = 0;
			string tmp_str = "";
			for (int j = i; j < str.length(); ++j) {
				tmp_str += str[j];
				if (str[j] == '(')
					++left_bracket;
				else if (str[j] == ')')
					++right_bracket;
				if (left_bracket == right_bracket) {
					i = j;
					++i;
					break;
				}
			}
			if (str[i] - '0' >= 0 && str[i] - '0' <= 9) {
				tmp_str += str[i];
				if (str[i + 1] - '0' >= 0 && str[i + 1] - '0' <= 9)
					tmp_str += str[++i];
				++i;
			}
			delete_brackets(mp, tmp_str, coefficient);
		}
	}
	return;
}

void Caculate(map<string, int>& mp, string str)//判断数目
{
	int add_num = 0;
	for (int i = 0; i < str.length(); ++i)
		if (str[i] == '+')
			add_num += 1;
	string* temp_str = new string[add_num + 1];//存储每一个化学式
	add_num = 0;
	for (int i = 0; i < str.length(); ++i) {
		if (str[i] == '+')
			add_num += 1;
		else
			temp_str[add_num] += str[i];
	}
	for (int i = 0; i <= add_num; ++i)
		Caculate_func(mp, temp_str[i]);
	delete[]temp_str;
}

bool Is_Judge(map<string, int>& mp_1, map<string, int>& mp_2) {
	if (mp_1.size() != mp_2.size())
		return false;
	for (auto it1 : mp_1) {
		auto it2 = mp_2.find(it1.first);
		if (it2 == mp_2.end())
			return false;
		else
			if (0 != memcmp(&it1.second, &it2->second, sizeof(int)))
				return false;
	}
	return true;
}

bool classification(map<string, int>& mp_1, map<string, int>& mp_2, string str) //以等号分段
{
	string head_str = "";
	string end_str = "";
	int len = 0;
	for (; str[len] != '='; ++len);
	head_str = str.substr(0, len);
	end_str = str.substr(len + 1, str.length() - len - 1);
	Caculate(mp_1, head_str);
	Caculate(mp_2, end_str);
	if (Is_Judge(mp_1, mp_2))
		return true;
	else
		return false;
}
int main()
{
	string str = "";//存化学式
	int total_num = 0;
	cin >> total_num;//总数读入
	while (total_num--) {
		map<string, int> mp_1;
		map<string, int> mp_2;
		cin >> str;//读入化学方程
		if (classification(mp_1, mp_2, str))//判断合法性
			cout << "Y" << endl;
		else
			cout << "N" << endl;
		mp_1.clear();
		mp_2.clear();
	}
	return 0;
}

测试结果
在这里插入图片描述


总结:
字符串真的很麻烦,还需要多加练习相关习题。

你可能感兴趣的:(CCF,CSP认证练习,CCF,CSP,CCF,CSP,软件能力认证)