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含有非法字符时程序异常结束,所以程序在使用时应留意非法字符并作相应的异常处理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值