#include<iostream>
#include<sstream>
#include<vector>
#include<map>
#include<string>
#include<algorithm>
using namespace std;
int toNumber(string item,int &pos) {
int num = 0;
while (isdigit(item[pos])) { //循环判断数字的位数
num = num * 10 + item[pos] - '0';
pos++;
}
return num;
}
struct Elem {//元素
string name;//名称
int num;//个数
Elem(string _name, int _num) :name(_name), num(_num) {}
};
void calc(string& str, map<string, int>& mp) {
stringstream ss(str);
string item;
while (getline(ss, item, '+')) {//以'+'分割获得单项式
int preNum=1; //单项式前置系数,默认为1
int i = 0; //充当单项式中指针,记录单项式处理到第几位了
vector<Elem>arr;
if (isdigit(item[0]))
preNum = toNumber(item,i);//记录单项式系数
while (i != item.size()) { //处理单项式内部元素
if (isdigit(item[i])) { //遇到数字
int num = toNumber(item, i);
if (arr[arr.size() - 1].name == ")") {//若上一个为右括号,则把前面到最近一个左括号的元素全部累乘
int j = arr.size() - 1;
arr[j].name = "*";//将右括号标记为*,代表已经处理过该右括号
while (arr[--j].name != "(") {//向前循环
arr[j].num *= num;
}
arr[j].name = "*";
}
else {
arr[arr.size() - 1].num *= num;//若没有右括号则只把前一个元素的个数累成
}
}
else if (isupper(item[i])) {//遇到大写字母
string name = "";
name = item[i++];
if (islower(item[i])) { //若同时下一个为小写字母
name += item[i++];
}
arr.push_back(Elem(name, 1));
}
else if (item[i] == '(') { //遇到左括号
arr.push_back(Elem("(", 1));
i++;
}
else if (item[i] == ')') { //遇到右括号
arr.push_back(Elem(")", 1));
i++;
if (!isdigit(item[i])) {
item.insert(i,"1");
}
}
}
for (int j = 0; j != arr.size(); j++) {//将元素个数储存到map中,
if (arr[j].name == "*")
continue;
else
mp[arr[j].name] += arr[j].num * preNum;//"+="是因为同一元素可能会出现在不同单项式中
}
}
}
bool judge(map<string, int>& left, map<string, int>& right) {
if (left.size() != right.size())
return false;
else {
for (map<string, int>::iterator it = left.begin(); it != left.end(); it++) {
if (right[it->first] != it->second)
return false;
}
}
return true;
}
int main() {
int n;
cin >> n;
for (int i = 0; i < n; i++) {
stringstream ss;//使用文件流,方便进行字符分割
string str, lstr, rstr;
map<string, int> left, right;
cin >> str;
ss.str(str);
getline(ss, lstr, '='); //getline每次读取一行输入,默认以换行符作为分割,,也可以指定'='作为代替换行符
getline(ss, rstr); //不输入则默认换行符作为分割,即3Ba(OH)2+2H3PO4=Ba3(PO4)2+6H2O\n 被分别读取到了lstr和rstr中
calc(lstr, left);
calc(rstr, right);
if (judge(left, right))
cout << "Y" << endl;
else
cout << "N" << endl;
}
return 0;
}
CCF-19-12-3化学方程式(超简洁满分代码)
最新推荐文章于 2021-05-25 03:16:18 发布