创建一个简单的文本汇总算法的最有效方法

Most effective way to create a naive text summaring algorithm

本文关键字:算法 方法 有效 文本 创建 一个 简单      更新时间:2023-10-16

我正在构建一个简单的朴素文本摘要算法。算法是这样工作的:

  • 我的算法的第一步是删除所有停止词(英语中的停止词)
  • 在我的文本中只包含有实际含义的单词后,我将看看每个单词在文本中使用了多少次,以找到单词的频率。例如,如果"超级计算机"一词被使用5次,它将具有frequency = 5
  • 然后我将通过将sum of the frequencies of all words in the sentence除以number of the words in the sentence来计算每个句子的权重
  • 在最后一步,我将根据句子的长度对它们进行排序

我需要用C++(作为V8 NodeJS模块)编写这个算法,但问题是在过去几年里,我主要使用Javascript等高级脚本语言,而我在C++方面没有那么多经验。在javascript中,我可以使用regex删除所有停止词,然后找到频率,但在C++中似乎要复杂得多。

我想出了以下想法:

struct words {
    string word;
    int freq;
}
std::vector<words> Words;
  • 停止字将被预加载到V8本地数组或std::vector中
  • 对于文本中的每个单词,我将循环遍历所有停止词,如果当前单词不是停止词,则检查其是否在结构中,如果不是->将新的word添加到Words vector,如果存在,则将freq增加1
  • 在我找到所有单词的所有频率后,我将再次循环浏览文本,以找到每个句子的权重

有了这个想法,我脑海中出现了几个问题:

  1. 我的短信大多是1000多字。对于每一个循环通过100多个停止词的单词,仅仅为了找出停止词就要进行100000次迭代。这似乎真的无效
  2. 在我有了频率后,我需要用300多个单词(在向量频率中)在文本中循环1000多个单词,以计算每个句子的权重

我的想法似乎无效,但我对C++不太熟悉。

所以我的问题是,有没有更好的方法来做到这一点或优化我的算法,尤其是我上面列出的问题

我担心我的算法的性能,任何提示/建议都将不胜感激。

关于停止语,请查看std::unordered_set。您可以将所有的停止字字符串存储在std::unordered_set<string>中,然后当您有一个要比较的字符串时,调用count(string)查看它是否存在。

对于单词/频率对,请使用一些注释中的std::unordered_map。如果在一个地图查找中同时执行查找和插入操作,这将是最快的。试试这样的东西:

struct Frequency
{
    int val;
    Frequency() : val(0) {}
    void increment()
    {
        ++val;
    }
};
std::unordered_map<std::string, Frequency> words;
void processWord(const std::string str)
{
    words[str].increment();
}

words[str]在地图中搜索一个单词,如果不存在则添加该单词。新词将调用Frequency的构造函数,该构造函数初始化为零。所以你所要做的就是对每个单词调用processWord