2016-12-07 20 views
1

我正在C++中創建索引器應用程序。 每個唯一字的目錄的文本文件,我想存儲喜歡 - first_map <「字」,second_map <「文件對象引用」列表{行號}>什麼是插入到列表地圖的地圖的正確方法

爲了填補這一地圖第一次,我在目錄中逐字解析每個文件。爲推動數據到地圖上,我同時使用喜歡 -

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

得到一個編譯錯誤我想,如果內部映射值的類型爲int這會不會引發錯誤。 我也嘗試使用像 -

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

這也失敗了一個錯誤。 將數據插入此容器的正確方法是什麼?

完整源代碼如下─

#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

給出好消息:

使編譯器走在這行:

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

itstd::vector<File>::iterator,和pool

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

因此,爲了得到一個iterator普通File *,「& *」是典型的做法。

壞消息:

這是行不通的。只要std::vector<File>重新分配,其所有內容指針和迭代器都會失效。你的std::map將留下指示永遠不會降落。

如果對象,這個結構是被複制或移動的部分,一切都被從高軌道也核爆。

您將需要徹底重新考慮數據和容器的總體設計。

+0

謝謝,我會重新審視容器設計。任何建議你的一方製作一個數據冗餘度較低的高效容器。 – user1868132

+0

我最近不得不做一個哈希表與對列表的向量。它工作得很好。這會幫助你嗎? –

相關問題