CCF CSP2019.12 -- 化學方程式

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述


可能在第六個測試測試點存在問題,但是很無奈,沒找出來,樣例數據都通過了。
個人代碼如下,供參考

#include<iostream>
#include<string>
#include<string.h> 
#include<map>
#include<deque>
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;
}

測試結果
在這裏插入圖片描述


總結:
字符串真的很麻煩,還需要多加練習相關習題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章