首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在排序的STL容器中查找给定键的“最佳匹配键”

在排序的STL容器中查找给定键的“最佳匹配键”
EN

Stack Overflow用户
提问于 2008-10-20 13:45:32
回答 4查看 4.4K关注 0票数 7

问题

我有带时间戳的数据,我需要根据时间戳进行搜索,以便获得与我的输入时间戳最匹配的现有时间戳。

最好使用STL来解决这个问题。boost::*或stl::tr1::* (来自带有Featurepack的VS9 )也是可能的。

带时间戳的数据示例:

代码语言:javascript
运行
复制
struct STimestampedData
{
 time_t m_timestamp; // Sorting criterion
 CData m_data;       // Payload
}

使用stl::vectorsort()equal_range()的方法

因为mapset只允许我找到完全匹配的内容,所以我不能再使用它们中的任何一个。因此,现在我有了一个vector,当数据传入时,我会将数据追加到它。在搜索之前,我使用了<algorithm>sort(),并为它提供了一个自定义的比较函数。

之后,我使用<algorithm>equal_range()来查找具有指定值x的两个邻居,从这两个值中,我检查哪一个最接近x,然后得到我的最佳匹配。

虽然这并不太复杂,但我想知道是否有更优雅的解决方案。

也许STL已经有一个算法可以做到这一点,所以我不会在这里重新发明一些东西?

更新:线性搜索与二进制搜索

我忘了提一下,我有相当多的数据要处理,所以我不想线性搜索。

我之所以使用sort()对向量进行排序,是因为它具有随机访问迭代器,而map并非如此。使用map将不允许equal_range()以两倍的对数复杂度进行搜索。

我说的对吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2008-10-20 14:55:18

我将使用set::lower_bound查找匹配或更大的值,然后递减迭代器以检查下一个较低的值。您应该使用std::set而不是std::map,因为您的键嵌入在对象中-您需要提供一个函数来比较时间戳成员。

代码语言:javascript
运行
复制
struct TimestampCompare
{
    bool operator()(const STimestampedData & left, const STimestampedData & right) const
    {
        return left.m_timestamp < right.m_timestamp;
    }
};
typedef std::set<STimestampedData,TimestampCompare> TimestampedDataSet;

TimestampedDataSet::iterator FindClosest(TimestampedDataSet & data, STimestampedData & searchkey)
{
    if (data.empty())
        return data.end();
    TimestampedDataSet::iterator upper = data.lower_bound(searchkey);
    if (upper == data.end())
        return --upper;
    if (upper == data.begin() || upper->m_timestamp == searchkey.m_timestamp)
        return upper;
    TimestampedDataSet::iterator lower = upper;
    --lower;
    if ((searchkey.m_timestamp - lower->m_timestamp) < (upper->m_timestamp - searchkey.m_timestamp))
        return lower;
    return upper;
}
票数 7
EN

Stack Overflow用户

发布于 2008-10-20 14:10:14

我也会使用equal_range来做这样的事情。

如果您每次都对向量使用sort(),那么使用映射(或集合)可能更好,因为它总是自动排序的,并使用成员equal_range

但这取决于插入/查询的数量/数据量。(尽管对于在查询时总是需要排序的东西,映射将是我的第一选择,并且我只会在有非常好的理由时才使用向量)

票数 7
EN

Stack Overflow用户

发布于 2008-10-20 14:08:55

根据您的使用情况,您可以进行简单的线性搜索,而不是排序。提出一个“距离”函数,循环跟踪到目前为止的最佳匹配,以及它的距离。当你找到一个更好的匹配,忘记前一个,并保留新的和它的距离。当您遍历所有内容时,您就有了匹配项。

结果是O(N*S),其中N是向量中的项数,S是搜索次数。

您当前的方法是O((N+S)*LogN),如果搜索的数量很少且有界,这个值会更大。否则,排序/二进制搜索更好。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/218488

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档