欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ccfcsp认证--2020年12月场化学方程式

程序员文章站 2022-06-11 20:51:56
...

题目

ccfcsp认证--2020年12月场化学方程式
ccfcsp认证--2020年12月场化学方程式
ccfcsp认证--2020年12月场化学方程式
ccfcsp认证--2020年12月场化学方程式

C++代码

#include <bits/stdc++.h>
using namespace std;
struct Element{
 string name;
 int num;
 Element(string _name,int _num):name(_name),num(_num){};
};
int get_num(string& str,int& index){
 if(str.empty())
  return 0; 
 int coefficient=0;
 for(;index<str.size();++index){
  if(str[index]<='9'&&str[index]>='0'){
   coefficient=coefficient*10+str[index]-'0';
   continue;   
  }
  else
   break;
 }
 if(coefficient==0)
  coefficient=1;
 return coefficient;
}
void process(string& str,map<string,int>& str_map){
 string one;
 stringstream ss(str);
 while(getline(ss,one,'+')){
  int begin_index=0;
  int all_coefficient=get_num(one,begin_index);
  one=one.substr(begin_index,-1);
  //cout<<"coefficient is "<<all_coefficient<<"one is "<<one<<endl;
  int i=0;
  string element;
  while(i<one.size()){
   if(isupper(one[i])){
    if(i+1<one.size()&&islower(one[i+1])){//元素两个字母 
     element+=one[i];
     element+=one[i+1];
     i=i+2;
     if(i<one.size()&&isdigit(one[i])){
      int this_coefficient=get_num(one,i);
      if(str_map.find(element)!=str_map.end()) str_map[element]+=all_coefficient*this_coefficient;
      else str_map[element]=all_coefficient*this_coefficient;
      element.clear();      
     }
     else{
      if(str_map.find(element)!=str_map.end()) str_map[element]+=all_coefficient;
      else str_map[element]=all_coefficient;
      element.clear();
     }          
    }
    else{//元素一个字母
     element+=one[i];
     i=i+1;     
     if(i<one.size()&&isdigit(one[i])){
      int this_coefficient=get_num(one,i);
      if(str_map.find(element)!=str_map.end()) str_map[element]+=all_coefficient*this_coefficient;
      else str_map[element]=all_coefficient*this_coefficient;
      element.clear();      
     }
     else{
      if(str_map.find(element)!=str_map.end()) str_map[element]+=all_coefficient;
      else str_map[element]=all_coefficient;
      element.clear();
     }    
    }   
   }//遇到大写字母
   stack<int> bracket_index;
   stack<char> bracket; 
   vector<Element> all_element; 
   if(one[i]=='('){//遇到第一个左括号 
    bracket_index.push(all_element.size());
    bracket.push('(');
    ++i;
    while(!bracket.empty()){
     if(isupper(one[i])){
      if(i+1<one.size()&&islower(one[i+1])){//元素两个字母 
       element+=one[i];
       element+=one[i+1];
       i=i+2;
       if(i<one.size()&&isdigit(one[i])){
        int this_coefficient=get_num(one,i);
        all_element.push_back(Element(element,this_coefficient*all_coefficient)); 
        element.clear();      
       }
       else{
        all_element.push_back(Element(element,all_coefficient)); 
        element.clear();
       }          
      }
      else{//元素一个字母
       element+=one[i];
       i=i+1;     
       if(i<one.size()&&isdigit(one[i])){
        int this_coefficient=get_num(one,i);
        all_element.push_back(Element(element,this_coefficient*all_coefficient));
        element.clear();
              
       }
       else{
        all_element.push_back(Element(element,all_coefficient));
        element.clear();
       }    
      }   
     }//遇到大写字母
     if(one[i]=='('){
      bracket_index.push(all_element.size());
      bracket.push('(');
      ++i;      
     }
     if(one[i]==')'){
      int this_coefficient=1;
      if(bracket.top()=='('){//遇到配对的括号
       i=i+1;
       if(i<one.size()&&isdigit(one[i]))
        this_coefficient=get_num(one,i);
       for(int i=bracket_index.top();i<all_element.size();++i)
        all_element[i].num*=this_coefficient; 
      }
      bracket.pop();
      bracket_index.pop();
       
     }  
    }
    for(int i=0;i<all_element.size();++i){
     if(str_map.find(all_element[i].name)!=str_map.end()) str_map[all_element[i].name]+=all_element[i].num;
     else str_map[all_element[i].name]=all_element[i].num;
    }
    all_element.clear();   
   } 
  }    
 } 
}
int main(){
 int n;
 scanf("%d",&n);
 getchar();
 string s;
 map<string,int> left_map;
 map<string,int> right_map;
 for(int i=0;i<n;++i){
  //read>>s;
  cin>>s;
  int equal_sign=s.find_first_of('=');
  string left=s.substr(0,equal_sign);
  string right=s.substr(equal_sign+1,-1);
  process(left,left_map);
  //cout<<endl<<endl;
  process(right,right_map);
  
  if(left_map==right_map)  cout<<"Y"<<endl;
  else                   cout<<"N"<<endl;    
  /*for(auto it=left_map.begin();it!=left_map.end();++it)
   cout<<it->first<<":"<<it->second<<endl;
  cout<<endl;
  for(auto it=right_map.begin();it!=right_map.end();++it)
   cout<<it->first<<":"<<it->second<<endl;*/
  left_map.clear();
  right_map.clear();
 }
 return 0;
}

总结

1.对一些序列式的处理问题,不要尝试用分类的想法去做,因为可能分类的情况很多,无法想到所有的分类

学到的知识

1.str.substr(size_t pos=0,size_t npos)当npos+pos大于字符串长度时程序不会异常结束,子串会一直取到str的末尾
2.处理字符串时可在函数开始时加一个字符串是否为空的判断,如果为空函数返回
3.stoi(string str)等函数当str含有非法字符时程序异常结束,所以程序在使用时应留意非法字符并作相应的异常处理