保持排序序列,不包含小于谓词
Keeping sorted sequence without a less-than predicate
我希望保留一个排序的项目队列,在那里我希望能够弹出具有最低值的项目(有点像std::priority_queue
)。项值是连续的并且不断增加。但是,这些项没有定义小于比较,它们只有is-previous
和is-next
谓词(其中A is-previous B
==B is-next A
),它们还支持++
或--
。
我想知道是否有任何算法可以基于这样的谓词对值进行(部分)排序?或者,有没有更好的方法来跟踪这样的队列?
这个问题发生在模运算中——项目由整数指定,但由于模运算,小于和大于失去了意义,不能再用于排序。
选择的语言是C++,但我想我可以移植大多数合理的语言。
编辑
对所有试图回答的人来说,在编写示例代码时,我意识到最初的问题格式不正确。这真的很尴尬,但我想强调的是,你的时间没有浪费,因为我为此汗流浃背了一个小时,10分钟后我意识到这是多么的错误。不管怎样,这就是我想要的行为:
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)
。则CCD_ 11和CCD_。
如果您有整数和模数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>>
来获得相同的复杂性,但节省空间。
也可以使用CCD_ 20;这两种操作只提供了摊销的恒定时间,但在实践中可能会快得多。
在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)
});
这里的要求是关系是prev必须是一个严格的弱序。
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从包含m行的文件中提取n行,必要时(惰性地)重复该文件
- 编译包含字符串的代码时遇到问题
- c++库的公共头文件中应该包含什么
- 将包含C样式数组的对象初始化为成员变量(C++)
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 是否需要删除包含对象的"pair"?
- 函数何时会在c++中包含stack_Unwind_Resume调用
- 如何将包含epoch时间的十六进制字符串转换为time_t
- 使用mongocxx驱动程序时包含头文件问题
- 如何在h文件中包含.o对象文件
- 在混合代码库中将C转换为C++时出现许多包含错误
- VS2017,C++包含目录与附加包含目录,子文件夹包含失败-但为什么
- cmath抛出错误C2062、C2059、C2143和C2447.cmath包含在矢量文件中
- 为什么您需要C++头文件的包含保护
- 无法在UE4中包含BP类到CPP类
- g++ 说函数不存在,即使包含正确的标头
- 如何在将秒转换为分钟且余数小于 10 秒时包含前导零
- 编写一个函数,返回一个堆栈,该堆栈包含所有小于给定数字的元素,并且顺序相同
- 保持排序序列,不包含小于谓词