如何使用STL获得中值的索引

How to obtain the index of the median using STL?

本文关键字:索引 何使用 STL      更新时间:2023-10-16

之前已经讨论过如何计算数字数组的中值。例如,您可以参考使用STL容器进行中值计算时的正确方法是什么?。现在我有一个不同的问题,那就是如何获得原始STL容器中中值的索引。为了说明我的问题,我举了一个例子:

vector<int> myarray;
myarray.push_back(3);
myarray.push_back(1);
myarray.push_back(100);
myarray.push_back( 20);
myarray.push_back(200);
int n = myarray.size()/2;
nth_element(myarray.begin(), myarray.begin()+n, myarray.end());
int median = myarray[n];

在上面的代码中,我可以得到中值,但我不能在原始向量数组(4)中得到它的索引。有什么想法吗?谢谢

我认为没有直接的方法可以做到这一点。

您排序的向量已更改其顺序,因此在中搜索将始终返回n

您需要保存原始矢量的副本,并在其中进行搜索。请记住,如果原始矢量包含重复的矢量,您将不知道它们中的哪一个实际上被放在了位置n(如果这与您有任何相关性)。

作为替代方案,您可以查看nth_element的实现,并实现自己的版本,该版本还报告找到的第n个元素的原始位置。

如果可以搜索元素

vector<int>::iterator itOfMedian = std::find(myarray.begin(), myarray.end(), median);
int index = itOfMedian - myarray.begin();

应该做到这一点。

编辑

看来你说得有道理。nth_element对其参数向量进行排序。。。因此

vector<int> myArrayCopy = myarray;
// find median in myArrayCopy
vector<int>::iterator itOfMedian = std::find(myarray.begin(), myarray.end(), median);
int index = itOfMedian - myarray.begin();

您可以使用std::nth_element来查找中值元素的迭代器。然而,这会对向量进行部分排序,因此您需要使用一个副本:

  std::vector<int> dataCopy = myarray;
  // we will use iterator middle later
  std::vector<int>::iterator middle = dataCopy.begin() + (dataCopy.size() / 2);
  // this sets iterator middle to the median element
  std::nth_element(dataCopy.begin(), middle, dataCopy.end());
  int nthValue = *middle;

现在情况变得复杂了。您有一个与中值相对应的值。您可以在原始向量中搜索它,并使用std::distance获得索引:

std::vector<int>::iterator it = std::find(myarray.begin(), myarray.end(), nthValue);
std::vector<int>::size_type pos = std::distance(myarray.begin(), it);

然而,这仅在myarray中不存在nthValue的副本的情况下有效。

很抱歉挖掘了一个老话题,但这里有一个很好的方法。利用nth_element将按第一个元素对一对进行排序的事实;考虑到这一点,创建一个成对的向量,其中成对的第一部分是要参与中值计算的值,第二部分是索引。修改您的示例:

vector<pair<unsigned int, size_t>> myarray;
myarray.push_back(pair<unsigned int, size_t>(  3, 0));
myarray.push_back(pair<unsigned int, size_t>(  1, 1));
myarray.push_back(pair<unsigned int, size_t>(100, 2));
myarray.push_back(pair<unsigned int, size_t>( 20, 3));
myarray.push_back(pair<unsigned int, size_t>(200, 4));
int n = myarray.size()/2;
nth_element(myarray.begin(), myarray.begin()+n, myarray.end());
int median = myarray[n].first;
int medianindex = myarray[n].second;

当然,myarray已经被重新排列,因此myarray[medianindex]不是中值。如果在nth_element之前复制,则medianindex将是所需的索引。