使用快速排序对可能包含无穷大的容器进行排序安全吗
Is it safe to sort a container which may contain infinities using quicksort?
我已经意识到,为了使快速排序工作,所有的无穷大都必须相等。
换句话说,这样的标准是不够的:
class Entity
{
public:
float value() const;
bool valueIsInfinite() const;
};
class Criterium
{
bool operator()(Entity left, Entity right)const
{
if (left.valueIsInfinite())
return false;
return left.value() < right.value();
}
}
const Criterium criterium;
QVector<Entity> container;
qSort<container.begin(), container .end(), criterium>
这种排序失败了,因为并不是所有的无穷大根据标准都是相等的。不相等性取决于实体输入运算符的顺序。我发现,这样的命令失败了。
我需要这样的东西:
class Criterium
{
bool operator()(Entity left, Entity right)const
{
if (left.valueIsInfinite() && right.valueIsInfinite())
return false;
if (left.valueIsInfinite() && !right.valueIsInfinite())
return false;
if (!left.valueIsInfinite() && right.valueIsInfinite())
return true;
return left.value() < right.value();
}
}
但假设不是
float Entity::value() const;
bool Entity::valueIsInfinite() const;
方法,我只想使用
float Entity::value() const;
让它返回
std::numeric_limits<float>::infinity();
在
bool Entity::valueIsInfinite() const;
将返回true。
现在我测试了这种方法,它似乎有效。但我关心的是,无穷大可能以其他方式出现。例如:
float otherInfinity = exp(std::numeric_limits<float>::infinity());
这个无穷大似乎是一样的。但我想确定一下。我知道C++标准没有提到浮点运算实现的细节,但如果我使用gcc,它在所有情况下都安全吗?我的意思是,在gcc中,所有的无穷大都是相等的吗?对一个漂浮物容器进行分类安全吗?漂浮物容器可能包含在不同场合出现的无限量?
如果不存在NaNs,无穷大可以用正则运算符<
:
- +∞<+∞为false:
<
不可伸缩 - 如果+∞<x为真,则x<+∞对于非无穷大值为假:
<
是反对称的 - 如果+∞<x为真并且x<y为真,则+∞<y为真:
<
是可传递的 - 如果+∞与x不可比(不小于,不大于),并且x与y不可比,则+∞与y不不可比:
<
显示等价的瞬态性
(类似性质对-∞有效)
给定这些属性,不带NaNs的浮点上的operator<
是严格的弱排序,因此适用于标准库样式的排序操作。
然而,有了NaNs,反对称性就被打破了:NaN<1为假,并且1<NaN也是假的。您可以通过在所有非NaN之前或之后订购所有NaN来解决此问题,其方式类似于您提出的策略:
struct Criterion
{
bool operator()(Entity left, Entity right)const
{
// NaNs come before non-NaNs
if (isnan(left.value()) && isnan(right.value()))
return false;
if (!isnan(left.value()) && isnan(right.value()))
return false;
if (isnan(left.value()) && !isnan(right.value()))
return true;
return left.value() < right.value();
}
}
(isnan
可以在C++11标准库中找到,或者很容易实现为return x != x;
)
由此,我们得到NaN<1为真,并且1<NaN为false,而其他属性仍然有效。
如果您使用这个:
bool operator()(Entity left, Entity right)const
{
return !(left.valueIsInfinite() && right.valueIsInfinite())
&& left.value() < right.value();
}
那么不定式被认为是同一顺序的,因为没有一个在另一个之前。。。
相关文章:
- 从不同线程使用int64的不同字节安全吗
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 二叉排序树无法编译
- 虚拟决赛作为安全
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 仅使用绝对值对数组进行排序,并在C++中显示实际值
- C++选择排序算法中的逻辑错误
- 使用C++程序合并排序没有得到正确的输出
- 计算排序向量的向量中唯一值的计数
- 如何将元素添加到数组的线程安全函数?
- 排序算法c++
- 使用2个键的cpp-stl::优先级队列排序不正确
- 将结构向量排序为子组
- 在c++中尝试对对象数组进行排序时,出现std:bad_alloc错误
- 如何对点云数据进行排序
- C++中的线程安全删除
- 通过网络、跨平台传递std::变体是否安全
- 使用原子指令确保映射访问安全,是否可以使用两个不同的原子对指令进行重新排序
- 使用快速排序对可能包含无穷大的容器进行排序安全吗
- 对共享数据的线程安全访问 - 读/写实际发生,不会发生重新排序