3
我有std::multiset
如果我從std::multiset::begin()
迭代到std::multiset::end()
我會得到排序的元素。我如何在這個std::multiset
其他獲得中間元素比迭代從std::multiset::begin()
到std::multiset::begin() + size()/2
std :: multiset並找到中間元素
我有std::multiset
如果我從std::multiset::begin()
迭代到std::multiset::end()
我會得到排序的元素。我如何在這個std::multiset
其他獲得中間元素比迭代從std::multiset::begin()
到std::multiset::begin() + size()/2
std :: multiset並找到中間元素
這裏是一個解決方案,使中位值的std :: multiset的:
template<class T>
double GetMedian(const std::multiset<T>& data)
{
if (data.empty())
return 0;
const size_t n = data.size();
double median = 0;
auto iter = data.cbegin();
std::advance(iter, n/2);
// Middle or average of two middle values
if (n % 2 == 0)
{
const auto iter2 = iter--;
median = double(*iter + *iter2)/2; // data[n/2 - 1] AND data[n/2]
}
else
{
median = *iter;
}
return median;
}
如果你需要值絕對偏差( mdev)例如:
template<class T>
double GetMedianAbsoluteDeviation(const std::multiset<T>& data)
{
const double fMedian = GetMedian(data);
std::multiset<double> diff;
for (const auto& x : data)
{
diff.insert(std::abs(fMedian - x));
}
return GetMedian(diff);
}
謝謝!我更新了評論的文字部分。代碼不變。 – Sergey
沒有其他辦法,除非事先知道中間元素是什麼,或者您使用不同的數據結構。 – john
這是可能的,但非封裝黑客的便攜式解決方案。例如。 gcc std :: multiset <>使用_Rb_tree,其中_M_begin()僅指向集合的中間。但是_Rb_tree的實現是私有的 - 所以你必須用reinterpret_cast <>或者其他的方法破解這個封裝,而這個_Rb_tree的實現細節就是gcc現在使用的 - 我們不能確定它即使在不同版本的gcc中也是可移植的。 – PiotrNycz