2016-12-07 2 views
1

私はC++でインデクサーアプリケーションを作成しています。 ディレクトリのテキストファイル内の各ユニークワード、私は first_map < like-保存したい「言葉」を、<「ファイルオブジェクトの参照」をsecond_map、リスト{行番号}>リストのマップのマップに挿入する正しい方法は何ですか

このマップを初めてを埋めるために、私はディレクトリ内の単語ごとに各ファイルを解析しています。マップにデータをプッシュするには、

pool[token][it].push_back(count); 

like-使用している間、私はコンパイルエラーを取得しています私は、内側のマップ値がint型である場合、これはエラーをスローしないだろうと思います。 は、私はまた、これもエラーで失敗している

pool[token].insert(std::make_pair(it, count); 

like-使用するようにしてください。 このコンテナにデータを挿入する正しい方法は何ですか?コンパイラは、問題の行に離れて行くようにするには

完全なソースは

#include <sys/types.h> 
#include <sys/stat.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <dirent.h> 
#include <errno.h> 
#include <string.h> 
#include<iostream> 
#include<iterator> 
#include<algorithm> 
#include<string> 
#include<sstream> 
#include<list> 
#include<vector> 
#include<fstream> 
#include<map> 
#include<ctime> 

class File { 
    public: 
    std::string file_name; 
    int timestamp; 
    File(std::string name) : file_name(name) { 
     struct stat st; 
     int ierr = stat (file_name.c_str(), &st); 
     if (ierr != 0) { 
     std::cout << "error in getting timestamp"; 
     } 
     timestamp = st.st_mtime; 
    } 
}; 

class Location { 
    public: 
    std::vector<File> indexer; 
    virtual std::map<File*, std::list<int> > find_pattern(std::string& word); 
    Location(const char* in_dir){ 
     DIR* FD; 
     struct dirent* in_file; 
     /* Scanning the in directory */ 
     if (NULL == (FD = opendir (in_dir))) 
     { 
     fprintf(stderr, "Error : Failed to open input directory - %s\n", strerror(errno)); 
     throw -1; 
     } 
     while ((in_file = readdir(FD))) 
     { 
     if (!strcmp (in_file->d_name, ".")) 
      continue; 
     if (!strcmp (in_file->d_name, "..")) 
      continue; 
     indexer.push_back(File(in_file->d_name)); 

     } 
    } 
}; 
class TextFileLocation : public Location { 
    public: 
    std::map<std::string, std::map<File*, std::list<int> > > pool; 
    TextFileLocation(const char* in_dir) : Location(in_dir){ 

     for(auto it = indexer.begin(); it != indexer.end(); it++){ 
     std::ifstream file1(it->file_name); 
     if(!file1) 
     { 
      std::cout<<"Error opening output file"<<std::endl; 
      continue; 
     } 
     std::string line; 
     std::string token; 
     int count = 0; 
     while (std::getline(file1, line)) 
     { 
      count++; 
      std::map<File*, std::list<int> > *file_line = 
      std::istringstream ss(line); 
      while(std::getline(ss, token, ' ')) { 
       if(token.empty()) 
       continue; 
       pool[token][it].push_back(count); 
      } 
     } 
     } 
    } 
    std::map<File*, std::list<int> > find_pattern(std::string& word){ 
     return pool[word]; 
    } 
}; 

答えて

0

below-良いニュースを与えている

pool[token][&*it].push_back(count); 

itstd::vector<File>::iteratorで、 poolは、

std::map<std::string, std::map<File*, std::list<int> > > 

したがって、イテレータからプレーンFile *を得るには、 "& *"が一般的なアプローチです。

悪いニュース:

これはうまくいきません。 std::vector<File>が再割り当てされると、すべてのネイティブポインタとその内容のイテレータは無効になります。あなたのstd::mapに決して決して陸につかないように指示が残っています。

また、この構造体が含まれているオブジェクトがコピーまたは移動された場合でも、全てが高軌道から裸になります。

データとコンテナの全体的なデザインを完全に再考する必要があります。

+0

ありがとうございます、私はコンテナのデザインを見直します。データの冗長性の少ない効率的なコンテナを作成することをお勧めします。 – user1868132

+0

私は最近、ペアのリストのベクトルでハッシュテーブルを作成しなければなりませんでした。それは非常にきれいに働いた。これはあなたを助けるでしょうか? –

関連する問題