[英]Keeping sorted sequence without a less-than predicate
我想保持项目的排序队列,在这里我希望能够弹出具有最低值的项目(有点像std::priority_queue
)。 项目值是连续的并且不断增加。 但是,这些项没有定义小于比较的谓词,它们仅具有is-previous
和is-next
谓词(其中A is-previous B
== B is-next A
),它们还支持++
或--
。
我想知道是否有基于此类谓词的(部分)排序值算法? 或者,是否有更好的方法来跟踪此类队列?
在以模算术工作时会出现此问题-项由整数指定,但是由于取模,小于和大于小于它们的含义,并且不能再用于排序。
选择的语言是C ++,但是我想我可以移植大多数合理的语言。
编辑
在尝试编写示例代码时,所有试图回答问题的人都感到惊讶,我意识到最初的问题是不正确的。 这确实很令人尴尬,但我想强调的是,您的时间并没有浪费,因为我花了一个小时流汗,然后在十分钟内,我意识到这是错误的。 无论如何,这是我想要的行为:
template <class T>
class OrderedQueue {
std::vector<T> storage;
T next;
public:
OrderedQueue(T lowest_value = T())
:next(lowest_value)
{}
void Push(T t)
{
storage.push_back(t);
}
T Pop()
{
std::vector<T>::iterator it = std::find(storage.begin(), storage.end(), next);
if(it == storage.end())
throw std::runtime_error("no such element");
T value = *it;
storage.erase(it);
++ next;
return value;
}
};
我的问题是Pop()
接受O(N)
。 是否可以使用is-prev和is-next谓词来使其更快?
我的问题是Pop()需要O(N)。 是否可以使用is-prev和is-next谓词来使其更快?
您需要提供一种获取键的实际模块化整数表示形式的方法,例如Integer(x)
。 然后, Push
和Pop
都可以在恒定时间内执行。
如果您有整数和模数M
,请使用一个双向链接列表数组( std::list<T> queues[M]
),将Push(x)
为queues[Integer(x)].push_back(x)
和Pop
为
size_t i = Integer(next);
// check for existence, raise if necessary
T r = queues[i].front();
queues[i].pop_front();
return r;
如果M
很大,并且您希望大多数队列在大多数时间都是空的,则可以使用std::unordered_map<size_t, std::list<T>>
来获得相同的复杂度,但可以节省空间。
也可以使用std::deque
; 只能为这两种操作提供摊销的固定时间,但实际上可能要快得多。
在C ++中,您的类型不需要定义operator<
即可进行排序或在关联容器中使用。 容器和算法可以采用谓词来执行比较。 例如,使用is_pred
作为谓词对向量进行排序(假设它已经是一个函数对象或一个普通函数):
std::sort(v.begin(), v.end(), is_pred);
如果没有,您可以编写自己的函子适配器或lambda:
std::sort(v.begin(), v.end(), [](T const& lhs, T const& rhs) {
return apply_is_pred_predicate(lhs,rhs)
});
这里的要求是,关系is-prev必须是严格的弱阶。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.