思路借鉴:
https://blog.csdn.net/wingrez/article/details/103551680
知识点复习
(一)getline(is,str,delim)
将输入流is中的字符读入到字符串str中,知道遇到定界字符delim、到达文件尾或字符串的最大长度。
delim字符将被读取(从输入流中删除),但不被存储。
若第三个参数缺省,则默认为换行符。
(二)头文件sstream的应用
(三)C++ 11的简单学习
样例输入:
11
H2+O2=H2O
2H2+O2=2H2O
H2+Cl2=2NaCl
H2+Cl2=2HCl
CH4+2O2=CO2+2H2O
CaCl2+2AgNO3=Ca(NO3)2+2AgCl
3Ba(OH)2+2H3PO4=6H2O+Ba3(PO4)2
3Ba(OH)2+2H3PO4=Ba3(PO4)2+6H2O
4Zn+10HNO3=4Zn(NO3)2+NH4NO3+3H2O
4Au+8NaCN+2H2O+O2=4Na(Au(CN)2)+4NaOH
Cu+As=Cs+Au
样例输出:
N
Y
N
Y
Y
Y
Y
Y
Y
Y
N
C++ 代码
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <cctype>
#include <map>
using namespace std;
struct Element{//各元素的信息(名称、数量)
string name;
int num;
Element(string _name,int _num):name(_name),num(_num){}
};
int getNum(string s,int& index){//一个数可能由多位数字组成
int result = 0; //index使用引用类型,在返回调用函数的时候,index的值会被改变
while(isdigit(s[index])){
result = result * 10 +s[index] - '0';
index++;
}
return result;
}
void Calculate(string& s ,map<string,int>& mp){
stringstream ss(s);//将字符串s作为输入流
string item;
while(getline(ss,item,'+')){//item为 系数+化学式
vector<Element>arr;
int factor = 1;//若系数为空串,则系数默认为1
int i = 0;
if(isdigit(item[i])){//若系数不是空串,则获取系数
//在调用完getNum函数之后,i指向字符串item系数后边的元素
factor = getNum(item,i);
}
while(i<item.size()){
if(isupper(item[i])){//若为大写字母
string name;
name += item[i];//获取元素的名称
i++;
if(islower(item[i])){//该元素由两个字母组成
name += item[i];
i++;
}
arr.push_back(Element(name,1));
}else if(isdigit(item[i])){//项后边的系数
int behind = getNum(item,i);
if(arr[arr.size()-1].name == ")"){//该系数位于右括号后边
int j = arr.size() - 1;
arr[j].name = "*";//将右括号标记为*
j--;
while(arr[j].name != "("){
arr[j].num *= behind;//更新括号内元素个数
j--;
}
arr[j].name = "*";//将做扩报标记为*
}else{//系数在单个元素的后边
arr[arr.size()-1].num *= behind;
}
}else if(item[i]=='('){//处理左括号
arr.push_back(Element("(",0));
i++;
}else if(item[i]==')'){//处理右括号
arr.push_back(Element(")",0));
//若右括号后边没有没有数字,则该系数默认为1
//例如输入样例中的Na(Au(CN)2)
if(!isdigit(item[i+1]) || item.size()==i+1){
item.insert(i+1,"1");//在右括号的后边插入1
}
i++;
}
}
for(int i=0;i<arr.size();i++){
if(arr[i].name == "*"){
continue;
}else{//将所有元素乘上最前边的系数,更新mp
mp[arr[i].name] += arr[i].num * factor;
}
}
}
}
void judge(map<string,int>& left,map<string,int>& right){
if(left.size() != right.size()){//左右元素种类数不同,一定未配平
cout<<"N"<<endl;
return ;
}
//左右两边元素的种类数相同,比较各元素的个数
for(map<string,int>::iterator it = left.begin();it!=left.end();it++){
//若相同元素的个数不同
if(it->second != right[it->first]){
cout<<"N"<<endl;
return ;
}
}
cout<<"Y"<<endl;
}
int main(){
int n;
cin >> n;
getchar();
for(int i=0;i<n;i++){
map<string,int>left,right;//存放等式左右两边的元素及个数
string equation,str1,str2;
getline(cin,equation);//输入方程式
stringstream ss(equation);//将equation作为输入流
getline(ss,str1,'=');//以 = 为界定符,且不包含=
getline(ss,str2);
Calculate(str1,left);//处理等式左边
Calculate(str2,right);//处理等式右边
judge(left,right);
}
return 0;
}
C++ 11 代码
#include <iostream>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
#include <cctype>
#include <map>
using namespace std;
struct Element{
string name;
int num;
Element(string _name,int _num):name(std::move(_name)),num(_num){}
};
int getNum(string s,int& index){
int result = 0;
while(isdigit(s[index])){
result = result * 10 +s[index] - '0';
index++;
}
return result;
}
void Calculate(string& s ,map<string,int>& mp){
stringstream ss(s);
string item;
while(getline(ss,item,'+')){
vector<Element>arr;
int factor = 1;
int i = 0;
if(isdigit(item[i])){
factor = getNum(item,i);
}
while(i<item.size()){
if(isupper(item[i])){
string name;
name += item[i];
i++;
if(islower(item[i])){
name += item[i];
i++;
}
arr.emplace_back(name,1);
}else if(isdigit(item[i])){
int behind = getNum(item,i);
if(arr[arr.size()-1].name == ")"){
int j = arr.size() - 1;
arr[j].name = "*";
j--;
while(arr[j].name != "("){
arr[j].num *= behind;
j--;
}
arr[j].name = "*";
}else{
arr[arr.size()-1].num *= behind;
}
}else if(item[i]=='('){
arr.emplace_back("(",0);
i++;
}else if(item[i]==')'){
arr.emplace_back(")",0);
if(!isdigit(item[i+1]) || item.size()==i+1){
item.insert(i+1,"1");
}
i++;
}
}
for(auto & i : arr){
if(i.name == "*"){
continue;
}else{
mp[i.name] += i.num * factor;
}
}
}
}
void judge(map<string,int>& left,map<string,int>& right){
if(left.size() != right.size()){
cout<<"N"<<endl;
return ;
}
for(auto & it : left){
if(it.second != right[it.first]){
cout<<"N"<<endl;
return ;
}
}
cout<<"Y"<<endl;
}
int main(){
int n;
cin >> n;
getchar();
for(int i=0;i<n;i++){
map<string,int>left,right;
string equation,str1,str2;
getline(cin,equation);
stringstream ss(equation);
getline(ss,str1,'=');
getline(ss,str2);
Calculate(str1,left);
Calculate(str2,right);
judge(left,right);
}
return 0;
}