这个名字说明了一切,但要详细说明我有一个带时间戳的向量列表。它们大部分都是排序的,但会有一些乱序值。我想以有序的方式输出它们,但是矢量将以流式传输进入,我不想大量缓冲,因为我想及时输出我的结果。
所以我想保留一个带有N个向量的“向前看”列表。当我在新的向量中读到时,我想将它插入到列表中,然后从列表顶部弹出最旧的向量到输出,这样列表就会保持一个常数N向量的长度。
当我插入列表时,我希望对矢量进行排序并添加到列表中的正确位置,因为我认为这是最有效的方法。
我需要很好的效率,但不想浪费太长时间的实施和测试。所以我对简单的解决方案(例如重用现有的C ++结构,如果它们存在)感兴趣,并且如果能够提供明显的速度提升,则更难实现解决方案。我更愿意坚持标准的C ++,但如果有一个提升或类似的库完全符合我的需要,我很乐意听到它以防万一。
谢谢。
编辑:我感谢所有建议。但是,我忽略了时间戳并不是唯一的。时间戳只有第二个精度,所以实际上我很可能得到具有相同时间戳的多个向量。在这种情况下,我宁愿保留他们的订单,尽管没有必要。答案 0 :(得分:3)
看一下std::multiset
课程。
您应该检查其insert方法:
#include <set>
#include <functional>
const size_t max_item_number = 100;
struct your_type
{
std::string str;
time_t datetime;
};
class your_less : std::binary_function<your_type,your_type,bool>
{
public:
bool operator()( const your_type &left, const your_type &right ) const
{
return ( left.datetime < right.datetime );
}
};
std::multiset<your_type,your_less> store;
std::multiset<your_type,your_less>::iterator helper = store.begin();
helper = store.insert( helper, new_value );
helper = store.insert( helper, new_value );
// fixed size: remove the oldest value
// you could use it e.g. in loop
if ( store.size() == max_item_number )
{
store.erase( store.begin() );
helper = store.begin();
}
这样,如果订购了流,则插入时间可以保持不变。
答案 1 :(得分:1)
简单的选择: priority_queue O(lg n)插入和提取min,比set / multiset快很多(整数为3倍)并且占用内存较小
如果输入几乎已排序,则可以使用插入排序的某些变体。你只需要保留已排序的deque并将某些东西插回去,然后从前面弹出分钟。
答案 2 :(得分:0)
查看std::set
课程。
答案 3 :(得分:0)
如果你是在一个大的缓冲区中做到这一点,那么Timsort会非常出色。它可以利用部分排序。但是你说你不需要那个。
如果你需要在循环内部保持可管理的东西,你最好使用treap或红黑树。
Treaps平均速度很快(我最近在许多不同的条件下对Python中的树数据结构进行了性能比较,发现treaps总是最快或者平均速度第二快 - 其他两个有时比treaps快一点取决于工作量,但不一定如此)
据报道,红黑树的运行时间较短,标准偏差较小(平均而言,它们比平均水平慢,但如果这是一个实时或交互式应用程序,那么红黑树的效果可能更低操作时间变化)。