CCF CSP2019.12 -- 化学方程式
程序员文章站
2022-05-12 14:56:44
...
可能在第六个测试测试点存在问题,但是很无奈,没找出来,样例数据都通过了。
个人代码如下,供参考
#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;
}
测试结果
总结:
字符串真的很麻烦,还需要多加练习相关习题。