用于存储和计算最高得分K项的合适数据结构

时间:2011-02-21 20:51:31

标签: c++ sorting data-structures hashtable

我需要存储W项目。每个项目都有一个'string'属性和一个与之关联的'double'属性(项目的分数)。在每次迭代中,将额外的C项添加到集合中。迭代完成后,一些项目的分数会少量更新。现在,在W + C项目中,只有W项需要被推进到下一次迭代。将选择最高得分'W'项目,这些项目将转到下一代。 在每次迭代中,都会添加一组不同的“C”项。

W大约为10,000。 C大约为600。

在时间复杂度方面使用此功能的最佳数据结构是什么。哈希表,堆,二进制搜索树? 我正在使用C ++。一些提升参考将不胜感激

2 个答案:

答案 0 :(得分:1)

我会将这些值存储在两个并行结构中。首先,有一个double值数组,每个值都存储一个指针。接下来,将所有字符串与辅助整数一起存储在哈希表中。我们的想法是,数组中的指针指向散列表中的节点或trie持有与double关联的字符串,而每个字符串的整数值存储与该字符串配对的double的索引。

要在此结构中插入字符串/双精度对,请将字符串添加到散列表中,将double附加到数组中,然后将指针存储到数组中的新字符串,并将散列中的double的索引存储在散列中表。这具有复杂度O(k),其中k是字符串的长度。

要更改优先级,请在哈希表中查找字符串,然后获取数组中double的索引。然后,您可以修改该元素以更改tye关联的优先级。这也具有复杂度O(k)。

要丢弃除顶部B键/值对之外的所有对,请在阵列上运行选择算法,将顶部B元素放在数组的一部分中,将剩余的C元素放在另一部分中。每当执行交换时,请按照数组中的指针进入哈希表并更新刚刚交换的元素的索引。最后,遍历数组的最后C个元素,按照指针返回哈希表,并从表中删除它们指向的元素。这需要预期的O(n)时间来执行选择步骤,或者使用中位数算法算法的最坏情况O(n)时间,接着是O(n)时间来从哈希表中移除元素,预期的O(n)运行时间,其中n是结构中元素的数量。

总而言之,这为您提供O(k)插入和查找任何字符串,其中k是字符串长度,O(n)保留最佳元素,其中n是元素的总数。

答案 1 :(得分:1)

嗯,我认为你只需使用std::vector<Item>并在迭代结束时执行std::nth_element(在分数上)就可以了。例如。如果你想保留10000件物品,请这样做:

struct Item {
    double score;
    std::string name;
};

bool comparator(const Item& a, const Item& b) {
    return a.score > b.score;
};

if (items.size() > 10000) {
   // Make sure the 10,000 first elements contain the highest scores.
   items.nth_element(item.begin(), item.begin() + 10000, item.end(),
       comparator);
   // Only keep the first 10,000 elements.
   items.resize(10000);
}

实际上,如果你这样做,更新值(通过线性搜索和字符串比较)可能比排序慢。您可以通过将字符串哈希放入Item而不是纯字符串来加快比较。

如果您想要更快更新:在更新之前,请对字符串哈希值进行排序。然后,您可以进行二分搜索而不是线性搜索,以查找要更新的项目。