तुम सिर्फ अपने खुद के रोल कर सकते हैं:
template <typename RandomIt, typename KeyFunc>
void sort_by_key(RandomIt first, RandomIt last, KeyFunc func)
{
using Value = decltype(*first);
std::sort(first, last, [=](const ValueType& a, const ValueType& b) {
return func(a) < func(b);
});
}
तो KeyFunc
बहुत महंगा है, तो आप मूल्यों के साथ एक अलग वेक्टर बनाना होगा।
हम भी एक साथ एक वर्ग है कि हम अभी भी उपयोग करने की अनुमति देगा हैक कर सकते हैं std::sort
:
template <typename RandomIter, typename KeyFunc>
void sort_by_key(RandomIter first, RandomIter last, KeyFunc func)
{
using KeyT = decltype(func(*first));
using ValueT = typename std::remove_reference<decltype(*first)>::type;
struct Pair {
KeyT key;
RandomIter iter;
boost::optional<ValueT> value;
Pair(const KeyT& key, const RandomIter& iter)
: key(key), iter(iter)
{ }
Pair(Pair&& rhs)
: key(std::move(rhs.key))
, iter(rhs.iter)
, value(std::move(*(rhs.iter)))
{ }
Pair& operator=(Pair&& rhs) {
key = std::move(rhs.key);
*iter = std::move(rhs.value ? *rhs.value : *rhs.iter);
value = boost::none;
return *this;
}
bool operator<(const Pair& rhs) const {
return key < rhs.key;
}
};
std::vector<Pair> ordering;
ordering.reserve(last - first);
for (; first != last; ++first) {
ordering.emplace_back(func(*first), first);
}
std::sort(ordering.begin(), ordering.end());
}
या, कि अगर बहुत hacky है, यहाँ अपने मूल समाधान है, जो हमें हमारे अपने sort
लिखने के लिए की आवश्यकता है है
template <typename RandomIt, typename KeyFunc>
void sort_by_key_2(RandomIt first, RandomIt last, KeyFunc func)
{
using KeyT = decltype(func(*first));
std::vector<std::pair<KeyT, RandomIt> > ordering;
ordering.reserve(last - first);
for (; first != last; ++first) {
ordering.emplace_back(func(*first), first);
}
// now sort this vector by the ordering - we're going
// to sort ordering, but each swap has to do iter_swap too
quicksort_with_benefits(ordering, 0, ordering.size());
}
अब हालांकि हम reimplement करने के लिए है quicksort:
template <typename Key, typename Iter>
void quicksort_with_benefits(std::vector<std::pair<Key,Iter>>& A, size_t p, size_t q) {
if (p < q) {
size_t r = partition_with_benefits(A, p, q);
quicksort_with_benefits(A, p, r);
quicksort_with_benefits(A, r+1, q);
}
}
template <typename Key, typename Iter>
size_t partition_with_benefits(std::vector<std::pair<Key,Iter>>& A, size_t p, size_t q) {
auto key = A[p].first;
size_t i = p;
for (size_t j = p+1; j < q; ++j) {
if (A[j].first < key) {
++i;
std::swap(A[i].first, A[j].first);
std::iter_swap(A[i].second, A[j].second);
}
}
if (i != p) {
std::swap(A[i].first, A[p].first);
std::iter_swap(A[i].second, A[p].second);
}
return i;
}
,210
कौन सा, एक सरल उदाहरण दिया:
int main()
{
std::vector<int> v = {-2, 10, 4, 12, -1, -25};
std::sort(v.begin(), v.end());
print(v); // -25 -2 -1 4 10 12
sort_by_key_2(v.begin(), v.end(), [](int i) { return i*i; });
print(v); // -1 -2 4 10 12 -25
}
पायथन का 'कुंजी' फ़ंक्शन मूल रूप से [श्वार्टज़ियन ट्रांसफॉर्म] (http://en.wikipedia.org/wiki/Schwartzian_transform) को समाहित करता है। शायद यह एक सहायक Google खोज शब्द है? –
लेकिन पायथन मूल रूप से 'cmp' की बजाय फ़ंक्शन की तुलना करता था, जो वास्तव में एक सी निर्माण है। –
@MartijnPieters: अच्छा, मैं उस शब्द को कभी नहीं जानता था! धन्यवाद। – Claudiu