我有一个对象向量v,它使用自定义函数sortproc
进行排序:
std::sort(v.begin(), v.end(), sortproc);
在排序数组之前,我想提前知道sortproc的调用次数。
我尝试了什么?我尝试克隆该向量,然后对副本进行排序并计算sortproc被调用的次数。我通过增加一个计数器来做到这一点。然后,在对副本进行排序后,我读取计数器的值并再次对原始向量进行排序。这有效,但效率非常低,因为它完成了两次整个工作。是否有可能以更有效的方式做到这一点?
答案 0 :(得分:3)
几乎肯定不是。我想到的两个障碍是:
1)标准没有定义std::sort
使用的算法,因此便携式代码无法确切地知道执行了多少次比较,而不仅仅是尝试它。
2)即使您确实知道算法,我认为对于合理的排序算法来说,计算所需的比较次数并不比找出反转的数量更容易,反转的数量本身与排序具有相同的复杂性。因此,您无法获得更高效的解决方案。
2的解决方法是,如果sort
算法是这样的,那么比较的数量不取决于数据排序的接近程度,而只取决于数据的大小。使用该属性设计排序算法并非太多。它可能不如“真实”排序算法有效,但可能比排序两次更有效。
因此,例如在合并排序中,通常当合并的一侧耗尽时,将另一侧的剩余部分直接复制到目标中。如果在那时你做了一堆额外的冗余比较,仅仅是为了弥补数字,那么比较的数量将不依赖于输入的顺序。无意义的比较次数最差的情况是总数的一半,所以它不应该比排序两次更糟糕。这不是与std::sort
的“公平”比较,因为合并排序不是std::sort
的有效算法:它使用了太多的额外内存。
排序网络也使用固定数量的比较,但对std::sort
也不利,因为您需要知道设计网络的项目数...