在C ++中创建用于字符串操作的哈希表

时间:2013-08-22 13:13:12

标签: c++ hash hashtable

我正在尝试处理文章内容或任何段落[每个字符串]。首先,我将使用strtok()转换为单词。

之后我希望将每个单词存储在哈希表中(因为我认为这是处理大数据的唯一方法)。在处理每个单词时,我想存储每个单词的出现次数。最后,我希望获得最长时间出现的单词。

unordered_map存储具有键值的元素,并允许使用键快速检索元素。这可能对我有用。

我对C ++并不擅长,所以想要一些意见。

  1. char *ch ="content of article"中存储整个包含是继续或string :: str的好方法吗?我只熟悉第一个。对于第二部分,我在使用函数时感觉很复杂。

  2. 将整个内容(字符串)存储到unordered_map()中,然后我如何创建包含元素作为单词的哈希表,并将其与它一起出现。然后我可以得到最大出现的词吗?

  3. 是否还有其他C ++功能可以帮助我做我想做的事。

5 个答案:

答案 0 :(得分:3)

您需要的数据结构似乎需要执行多项操作:按键(字)查找每个键的字符串值(计数)。但您也希望能够打印频繁的作品,在这种情况下,您需要按值排序。

所有标准容器都没有开箱即用。由于第一次操作将频繁发生,而第二次操作只发生一次,因此您应该选择最适合第一次操作的容器。

std :: map和std :: unordered_map都可以。

请尝试以下操作:

std::map<std::string, int>

unordered_map std::map<std::string, int>

要按频率顺序打印所有作品,您必须将其复制到另一个结构中然后对其进行排序。或者它在一次操作中。您可以将所有内容复制到

std::map<int, std::string>

然后只打印它。

答案 1 :(得分:2)

  

我希望将每个单词存储在哈希表中(因为我认为这是处理大数据的唯一方法)。在处理每个单词时,我想存储每个单词的出现次数。

这是一些让你入门的伪C ++:

std::unordered_map<std::string, int> occurrences;
while (more_words_available)
{
    std::string word = fetch_next_word();
    ++occurrences[word];
}
  

如何在while?

中打印每个单词的出现次数值

你有C ++ 11编译器吗?然后使用新的foreach循环:

for (auto p : occurrences)
{
    std::cout << p.first << " occurred " << p.second << " times.\n";
}

否则,使用带迭代器的传统for循环:

for (std::unordered_map<std::string, int>::iterator it = occurrences.begin();
                                                    it != occurrences.end();
                                                    ++it)
{
    std::cout << it->first << " occurred " << it->second << " times.\n";
}

答案 2 :(得分:1)

  1. 使用字符串总是更容易
  2. 单词可用作键并计为值。基于密钥的检索来自unordered_map。获取具有最大计数的单词将需要迭代整个地图。 你的问题是你需要2个指数。
  3. 考虑使用Boost :: MultiIndex在容器中创建2个索引。

答案 3 :(得分:1)

如果您的文章位于文件test.txt中,那么您可以按照以下方式创建地图:

#include<fstream>
#include<map>
#include<string>

using namespace std;
int main()
{
    ifstream in_file("test.txt");
    map<string,int> words;

    string tword;
    while(in_file >> tword)  //line 12
        words[tword]++;
}

您还可以将整个内容存储在istringstream ss中,然后使用它代替上面的in_file

while(ss >> twords)  //line 12

答案 4 :(得分:1)

您不需要(也不想要)strtok。如果是空白区域 单词分隔符,只需使用>>读取字符串即可 做的伎俩;整个输入阶段将是:

std::unordered_map<std::string, int> counts;
std::string word;
while ( source >> word ) {
    ++ counts[word];
}

根据要求,您可能希望执行类似的操作 在计算之前将单词转换为小写,或者 从中剥离最终标点符号(以便wordWord和。{ Word.都是一样的。

对于按计数排序的访问,最简单的方法是复制 将地图内容转换为std::vector<std::pair<std::string, int>>并对其进行排序。 (别忘了你可以建造 来自两个迭代器的向量。所以这只是两行。)