HackerRank - Attribute Parser

問題URL : https://www.hackerrank.com/challenges/attribute-parser/problem

* getlineで行ごと取得したあと、cin >> wsで改行文字を捨てる。
https://qiita.com/iseki-masaya/items/70b4ee6e0877d12dafa8  を見ながら文字列split用の関数を作成

* 文字列に、tag1.tag2.tag3...のように、開始のtagが出てくるたびに追加し、\</tag?>が出るたびにtag?を削除していく。そのように作った文字列をキーにして、Valueを、キーを要素、Valueを値（string）にしたmapとした。

* テストケースの中に「\<tag6>￥n」 みたいな行があり、処理できずにsegmentation fault（Abort Call）になった。低能なのでメモリの使いすぎと思ってresizeやvector,mapのメモリ解放を試したり、continueを入れ忘れたりした。解決するのに1日かかった。


```c++
 #include <cmath>
 #include <cstdio>
 #include <vector>
 #include <iostream>
 #include <algorithm>
 #include <sstream>
 #include <map>
 #include <sstream>
 #include <unordered_map>
 using namespace std;
 
 vector<string> Split(const string &s,char delim){
     vector<string> elem(100);
     stringstream ss(s);
     string item;
     int i=0;
     while(getline(ss,item,delim)){
         if(!item.empty()){
             elem[i]=item;
         }else{
             break;
         }
         i++;
     }
     elem.resize(i);
     return elem;
 }
 
 template<typename K, typename V>
 void print_map(unordered_map<K,V> const &m)
 {
     for (auto const& pair: m) {
         std::cout << "{" << pair.first << ": " << pair.second << "}\n";
     }
 }
 
 template<typename K, typename V>
 void print_vector(vector<K,V> v){
     for(int i=0;i<v.size();i++){
         cout << v[i] << " "; 
     }
     cout << endl;
 }
 
 unordered_map<string,unordered_map<string,string>> M;
 
 void make_elem_map(int n){
     unordered_map<string,string> mtemp;
     vector<string> str;
     string m_key="";
     
     string s,value;
     for(int i=0;i<n;i++){
         getline(cin,s);
         cin >> ws;
         // printf("%d getline is ok s:%s\n",i,s.c_str());
         if(s[1]!='/'){
             str=Split(s,' ');
             // printf("%d str.size():%u\n",i,str.size());
             if(str.size()==1){
                 string tag=str[0].erase(0,1).erase(str[0].length()-1,1);
                 if(m_key.size()==0)m_key+=tag;
                 else m_key+=("."+tag);
                 continue;
             }
             for(int j=1;j<str.size()-2;j+=3){
                 value=str[j+2];
                 value.erase(0,1);
                 if(j==str.size()-3)value.erase(value.length()-2,2);
                 else value.erase(value.length()-1,1);
                 mtemp.insert(make_pair(str[j],value));
             }
             string tag=str[0].erase(0,1);
             if(m_key.size()==0)m_key+=tag;
             else m_key+=("."+tag);
             M.insert(make_pair(m_key,mtemp));
             mtemp.clear();
             str.clear();
         }else{
             string tag=s.erase(0,2).erase(s.length()-1,1);
             if(m_key.length()>tag.length())m_key.erase(m_key.find("."+tag), tag.length()+1);
             else m_key.clear();
         }
         // printf("%d is ok\n",i);
     }
     str.clear();
     str.shrink_to_fit();
     m_key.clear();
     m_key.shrink_to_fit();
 }
 
 int main() {
     /* Enter your code here. Read input from STDIN. Print output to STDOUT */
     int n,q;
     cin >> n >> q;
     cin >> ws;
     
     make_elem_map(n);
 
     // int cnt=0;
     // if(M.empty())printf("M is empty!\n");
     // else printf("M is not empty!\n");
     // for(auto const& pair: M){
     //     cout << cnt << endl << "parent key: " << pair.first << endl;
     //     // print_vector(pair.first);
     //     printf("value_map key,value: ");
     //     print_map(pair.second);
     //     cnt++;
     // }
 
     vector<string> query;
     string s;
 
     for(int i=0;i<q;i++){
         getline(cin,s);
         cin >> ws;
         query=Split(s,'~');
         if(M[query[0]].count(query[1])!=0)printf("%s\n",M[query[0]][query[1]].c_str());
         else printf("Not Found!\n");
     }
     
     return 0;
 }
```