合成地图:从另一个地图获取数据

时间:2019-01-24 11:07:44

标签: c++ dictionary vector stl

我需要使用map<string,int>来处理从文件中提取的单词,然后将它们复制到map<int, vector<string>, cmpDec >,并以降序打印。

我尝试将词频从文件中提取到map<string, int>,然后尝试将其复制到map<int, vector<string> >,但没有结果

我已经声明了2张地图:

map<string, int> text;
map<int, vector<string>, cmpDec> freq;

我从第一张地图中的文件中提取了带有频率的文字:

while (rf >> words) {
    text[words]++;
}

现在,我必须将频率放置在第二个映射中(必填),对于第二个映射,我需要首先生成int,以获得多个词频,vector包含每个频率的词,以及比较降低的频率。 现在,我正尝试通过以下方式将数据从第一个映射到第二个映射:

map<string, int>::iterator iter_map1 = text.begin();
map<int, vector<string>>::iterator iter = freq.begin();
vector<string>::iterator iter_v;
for (; iter_map1 != text.end(); ++iter_map1) {
   iter->first.insert(make_pair(iter_map1->second, iter->second.push_back(iter_map1->first)));
}

在iter-> second ....行上给出2个错误:

...\BagOfWords.cpp|56|error: request for member 'insert' in 'iter.std::_Rb_tree_iterator<_Tp>::operator-><std::pair<const int, std::vector<std::__cxx11::basic_string<char> > > >()->std::pair<const int, std::vector<std::__cxx11::basic_string<char> > >::first', which is of non-class type 'const int'|

... \ BagOfWords.cpp | 56 |错误:无效使用void表达式|

我在做什么错?是否有一种更简便的方法来从文件中提取单词(及其频率),并将其放在第二张地图上而又不会从第一张地图传递过来?

3 个答案:

答案 0 :(得分:2)

使用C++17,您可以执行 structured binding ,这在遍历map时很有帮助。

#include <map>
#include <vector>
#include <string>
#include <iostream>

using WordCounts       = std::map<std::string, int>;
using FrequencyOfWords = std::map<int, std::vector<std::string>, std::greater<int>>;

int main()
{
    WordCounts word_counts;
    FrequencyOfWords words_freq;
    std::vector<std::string> words = {"test", "hello", "test", "hello", "word"};

    for(const auto& word : words)
        word_counts[word]++;

    for(const auto& [word, count] : word_counts)
        words_freq[count].push_back(word);

    for (const auto& [freq, words] : words_freq)
    {
        std::cout << "freq " << freq << " words";
        for (auto const& word: words)
            std::cout << " " << word;
        std::cout << '\n';
    }
}

答案 1 :(得分:1)

我不认为您可以一口气做到这一点,因为您不知道这个词很重要。

首先,有一些建议。使用typedef(对于C ++ 11或更高版本,使用using)。这将为您节省一些打字时间,并确保您输入的类型正确。在您的代码freqiter中没有相同的基础容器类型(它们在使用的比较中有所不同)。

第二,尝试尽可能多地使用标准库。您没有显示cmpDec,但我想它是一个基于大于而不是默认小于的比较器。我希望看到std::greater<int>而不是自定义比较器。

对于您的错误,在一行中

iter->first.insert(...

iterfreq的开头,您正尝试插入first的{​​{1}}中。

这大概应该是

int

打破现实

  • freq[iter_map1->second].push_back(iter_map1->first); 这将使用freq[iter_map1->second]中的int字数来查找text中的条目。如果没有条目,将在freq中插入一个空条目。
  • freq,这会将.push_back(iter_map1->first)string插入到在上一步中找到或创建的text

这是我想达到的目标的完整示例。

vector

答案 2 :(得分:0)

也许我误解了这个问题,但是我认为以下内容可以满足您的要求(我更喜欢无序地图,因为它们速度更快,而且您似乎不需要排序)

std::unordered_map<std::string,int> word_counts;
std::string word;
while(input >> word)
    word_counts[word]++;

std::unordered_map<int,std::vector<std::string>> words_by_freq;
for(const auto& counted : word_counts)
    words_by_freq[counted::second].push_back(counted::first);