了解nth_element

时间:2018-05-05 16:57:44

标签: c++ algorithm vector nth-element

我很难掌握如何使用std::nth_element,因为我生锈了。

裁判说:

  

重新排列范围[first,last)中的元素,使得第n个位置的元素是排序序列中该位置的元素。

我想取一个向量子集的第n个元素,所以我想做这样的事情:

std::nth_element (v.begin()+start-0, v.begin()+nTh-1, v.begin()+end);

意味着从v获取向量start的子集,直到end(不包括),然后想象这个子集已经排序,定位{{ 1}}元素。

似乎我的理解是关闭的,因为这个玩具示例:

nTh

打印9作为请求的元素,而我会期待5.我想要的是什么?

2 个答案:

答案 0 :(得分:1)

尝试:

std::nth_element (myvector.begin(), myvector.begin()+ 4, myvector.end());

而不是:

std::nth_element (myvector.begin() + 1, 
                  myvector.begin() + 4, 
                  myvector.begin() + 5);

你正在洗牌,然后只为一个子序列调用nth_element。这样你就不能知道返回的元素应该是什么。如果您对整个序列执行此操作,则答案为 5

答案 1 :(得分:0)

  

我想取向量子集的第n个元素,所以我想   做这样的事情:

     

std :: nth_element(v.begin()+ start-0,v.begin()+ nTh-1,v.begin()+ end);

     

表示从一开始就取向量v的子集,直到   最后(不包括),然后想象该子集已排序,   定位nTh元素。

是的,是的。 但是这样做时,位置v [0]到v [start-1]和v [end]到v [v.size()-1]的任何元素都不会成为nth_element重排的一部分,它们将保留在他们是。您作为nth_element()的一部分的开头和结尾排除了这些元素的重新排列。

我认为你想要

std::nth_element (myvector.begin(), myvector.begin()+ 4, myvector.end());

要考虑整个向量(nth_element的第一个和第三个参数)。

这意味着无论random_shuffle在何处都对元素进行了混洗

std::random_shuffle (myvector.begin(), myvector.end());

因为nth_element正在考虑整个向量,所以nth_element的第二个参数(myvector中的第5个项目,如果已​​排序)应为5。请注意,由于nth_element的工作方式,前一个项目将小于5(并且在任何情况下,订单),然后下一项将超过5(且按任何顺序)。