之前已经讨论过如何计算数字数组的中位数。例如,您可以参考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)中得到它的索引。有任何想法吗?谢谢!
答案 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
将是所需的索引。