如何使用STL获得中位数指数?

时间:2012-07-19 07:47:22

标签: c++ stl

之前已经讨论过如何计算数字数组的中位数。例如,您可以参考What is the right approach when using STL container for median calculation?。现在我有一个不同的问题,那就是如何获得原始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)中得到它的索引。有任何想法吗?谢谢!

4 个答案:

答案 0 :(得分:6)

我认为没有直截了当的方法。

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

您需要保存原始矢量的副本,然后搜索。请记住,如果原始向量包含重复项,您将无法准确知道它们中的哪一个实际放置到位置n(如果这与您有任何关联)。

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

答案 1 :(得分:4)

如果它适合搜索元素

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();

答案 2 :(得分:3)

您可以使用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);

但是,只有在nthValue中没有重复myarray时,此功能才有效。

答案 3 :(得分:1)

很抱歉找到一个老话题,但这是一个很好的方法。利用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将是所需的索引。