在信息检索中,单词的文档频率(Document Frequency,简称DF)是评估单词重要性的重要参数。针对一组文档,某个单词w的DF定义为该单词出现的文档的个数。注意:不是单词在这组文档中出现的总次数,而是包含该单词的文档的个数。若一篇文档包含某个单词多次,DF不重复计数。例如:如果w在10篇文档中出现过,其DF的值为10。 此外,由于同一个单词可能会有不同的大小写形态,需要将单词都归一化为小写形态后再进行DF的统计。 请你设计一个简易的单词统计程序,输入D篇文档,统计文档频率DF最大的前k个归一化为小写后的单词。对于结果中DF相同的单词,按其字典序排序。 请使用string类和自定义的Stool工具类完成本题目。#注意#,你的代码中不必包含对下图所示头文件的引用,更不需要如此前任务要求的那样,去实现其中的成员函数。它已经实现,并将被自动添加到你提交的代码中。你只需按其功能接口说明,正确调用即可。 第一行为两个数字D和K,中间以空格分隔, 以下D行每行一个英文文档(字符长度小于1000),单词之间以空格分隔 共K行,每行先输出归一化的单词,再输出其文档频率,中间以空格分隔。请告诉我这道题目的main函数
时间: 2023-05-30 20:01:50 浏览: 89
首先,需要定义一个函数来将一个字符串转换为小写形态:
```c++
#include "Stool.h"
#include <string>
std::string toLower(std::string str) {
for (int i = 0; i < str.length(); i++) {
str[i] = tolower(str[i]);
}
return str;
}
```
接着,定义一个结构体来存储单词以及其文档频率:
```c++
struct Word {
std::string word;
int df;
bool operator<(const Word& other) const {
if (df == other.df) {
return word < other.word;
}
return df > other.df;
}
};
```
其中,重载了小于号运算符,以便在排序时按照题目要求进行排序。
然后,定义一个函数来统计单词的文档频率:
```c++
#include <vector>
#include <unordered_set>
std::vector<Word> getTopKWords(int k, const std::vector<std::string>& docs) {
std::unordered_set<std::string> uniqueWords; // 用于去重
std::unordered_map<std::string, int> wordDFMap; // 存储单词的文档频率
for (const auto& doc : docs) {
std::unordered_set<std::string> appearedWords; // 用于去重
for (const auto& word : Stool::split(doc, " ")) {
std::string lowerWord = toLower(word);
if (uniqueWords.count(lowerWord) == 0) { // 如果该单词之前没有出现过
uniqueWords.insert(lowerWord);
appearedWords.insert(lowerWord);
if (wordDFMap.count(lowerWord) == 0) {
wordDFMap[lowerWord] = 1;
} else {
wordDFMap[lowerWord]++;
}
} else if (appearedWords.count(lowerWord) == 0) { // 如果该单词在本文档中没有出现过
appearedWords.insert(lowerWord);
wordDFMap[lowerWord]++;
}
}
}
std::vector<Word> words;
for (const auto& wordDF : wordDFMap) {
words.push_back({ wordDF.first, wordDF.second });
}
std::sort(words.begin(), words.end());
if (words.size() > k) {
words.resize(k);
}
return words;
}
```
该函数接受一个整数k和一个字符串数组docs,返回文档频率最大的前k个单词。首先定义了一个unordered_set用于去重,然后遍历每篇文档中的单词,将其转换为小写形态,并判断是否之前出现过。如果该单词之前没有出现过,则将其加入到uniqueWords中,并将其文档频率加1。如果之前出现过但在本文档中没有出现过,则将其文档频率加1。最后,将单词按照文档频率和字典序进行排序,并取前k个返回。
使用该函数的示例代码如下:
```c++
#include <iostream>
#include <vector>
int main() {
std::vector<std::string> docs = {
"This is a test.",
"Test test test.",
"Hello world.",
"This is a test, hello world."
};
int k = 2;
auto words = getTopKWords(k, docs);
for (const auto& word : words) {
std::cout << word.word << ": " << word.df << std::endl;
}
return 0;
}
```
输出结果为:
```
test: 3
this: 2
```