तय समारोहक्रमबद्ध तत्वों, लेकिन रखने पर कुछ को
template <typename Container, typename Comparator, typename Predicate>
void sortButKeepSomeFixed (Container& c, const Comparator& comp, const Predicate& pred)
कंटेनर c
सॉर्ट करने के लिए आदेश देने की कसौटी comp
के अनुसार है, लेकिन उन तत्वों को संतुष्ट प्रकार के बाद pred
अपने मूल स्थान में स्थिर रहते जाएगा (यानी इस तरह से अप्रभावित)।
मैंने इसे फिट करने के लिए त्वरित क्रम को अनुकूलित करने की कोशिश की, लेकिन इसके बारे में सोच नहीं सका। अंत में, मैं कच्चे चयन तरह अनुकूल करने के लिए काम करवाने का फैसला किया:
#include <iostream>
#include <vector>
std::vector<int> numbers = {5,7,1,8,9,3,20,2,11};
template <typename Container, typename Comparator, typename Predicate>
void sortButKeepSomeFixed (Container& c, const Comparator& comp, const Predicate& pred) { // O(n^2), but want O(nlogn) on average (like quick sort or merge sort)
const std::size_t N = c.size();
std::size_t i, j, minIndex;
for (i = 0; i < N-1; i++) {
if (pred(c[i]))
continue; // c[i] shall not swap with any element.
minIndex = i;
for (j = i + 1; j < N; j++) {
if (pred(c[j]))
continue; // c[j] shall not swap with any element.
if (comp(c[j], c[minIndex]))
minIndex = j;
}
if (minIndex != i)
std::swap(c[i], c[minIndex]);
}
}
int main() {
sortButKeepSomeFixed (numbers,
std::greater<int>(), // Ordering condition.
[](int x) {return x % 2 == 0;}); // Those that shall remain fixed.
for (int x : numbers) std::cout << x << ' '; // 11 9 7 8 5 3 20 2 1
}
लेकिन समय जटिलता हे (एन^2) (मुझे लगता है कि) है। क्या कोई औसत समय पर शायद ओ (एनएलओएनएन) पर जटिलता में सुधार कर सकता है? दूसरे शब्दों में, रिकर्सन या ऐसा कुछ उपयोग करके, एक समग्र बेहतर एल्गोरिदम खोजें?
या शायद pred
को संतुष्ट करने वाले तत्वों को निकालने का एक बेहतर विचार है, std::sort
के साथ क्या छोड़ा गया है और फिर निकाले गए तत्वों को अपनी मूल स्थिति में वापस रखें? क्या यह और अधिक कुशल होगा, या यह सिर्फ इसे और खराब कर देगा?
अद्यतन: यह बीटा के सुझाव पर आधारित है (pred
पास नहीं करने वाले इटरेटर्स को सॉर्ट करना)। लेकिन हालांकि pred
पास करने वाले तत्व वास्तव में तय रहते हैं, अंत में सॉर्टिंग सही नहीं है।
template <typename Container, typename Comparator, typename Predicate>
void sortButKeepSomeFixed (Container& c, const Comparator& comp, const Predicate& pred) {
std::vector<typename Container::iterator> iterators;
for (typename Container::iterator it = c.begin(); it != c.end(); ++it) {
if (!pred(*it))
iterators.emplace_back(it);
}
std::vector<typename Container::iterator> originalIterators = iterators;
std::sort(iterators.begin(), iterators.end(),
[comp](const typename Container::iterator& x, const typename Container::iterator& y)
{return comp(*x, *y);});
for (int i = 0; i < originalIterators.size(); i++)
*originalIterators[i] = *iterators[i];
}
गलत उत्पादन 11 9 9 8 11 3 20 2 9
है जब यह 11 9 7 8 5 3 20 2 1
होना चाहिए।
आपका "बेहतर विचार" काफी अच्छा काम करेगा, ओ (एन लॉगएन)। – Beta
ओ (एन लॉगएन) 'std :: sort' के लिए स्वयं, लेकिन फिर तत्वों को हटाने पर खर्च किया गया समय और फिर उन्हें अपनी मूल स्थिति में वापस रखकर थोड़ा सा जोड़ता है, है ना? – prestokeys
यदि आप किसी 'वेक्टर' की तरह कुछ उपयोग करते हैं लेकिन तत्वों को सम्मिलित/निकालने में संभाल नहीं करते हैं, तो सम्मिलन/निकासी में 'ओ (एन)' की जटिलता है, इसलिए यह ठीक है। – mostruash