Karşılaştırma işleviniz oldukça karmaşık olduğundan, çok ayrıntılı bir şekilde yeniden yazdım, böylece olası her durum ayrı ayrı denetlenebilir. Ayrıca, her bir elemanın hangi bölüme girdiğine dair kararın farklı bir işleve ayrıldığını gördüm.
#include <algorithm>
#include <iostream>
#include <iterator>
int classify(int const i)
{
if (i%3==0 && i%2!=0) {
return 1;
}
else if (i%3!=0) {
return 2;
}
else {
return 3;
}
}
bool comp(int const a, int const b)
{
int const a_part = classify(a);
int const b_part = classify(b);
if (a_part==1) {
if (b_part==1) {
// both in first partition, order ascending
return a<b;
}
else {
// a in first partition, b not, so a always first
return true;
}
}
else if (a_part==2) {
if (b_part==1) {
// b comes before a
return false;
}
else if (b_part==2) {
// both in middle partition, order ascendingly
return a<b;
}
else {
// a in middle partition, b in last partition, so a always first
return true;
}
}
else { // (a_part==3)
if (b_part!=3) {
// a in last partition, b in first or middle partition,
// so b always comes first
return false;
}
else {
// both in last partition, order descending
return b<a;
}
}
}
int main()
{
int ar[8] = {18 ,5 ,24 ,9 ,12 ,6 ,2, 3};
std::sort(std::begin(ar),
std::end(ar),
comp);
std::copy(std::begin(ar),
std::end(ar),
std::ostream_iterator<int>(std::cout,
"\n"));
}
Çıktı:
$ ./SO
3
9
2
5
24
18
12
6
Ayı düşünülerek karşılaştırıcı Bunu yapan düşünmek hangi bir Strict Weak Ordering uyarmak zorunda, ama bir normalde Sıralama için kullanmak istiyorsunuz daha biraz farklıdır.
Daima değil kısa mümkün olduğunca, mümkün olduğunca açıkça şekilde yazın. Bazı karmaşık mantıklarınız varsa, parçalara ayırın, parçaları fonksiyonlara taşıyın ve bol miktarda yorum ekleyin. Unutmayın, diğer insanlar 6 ay içinde kendiniz de dahil olmak üzere, onu okumalı ve anlamalıdır.
Daha iyi bir yaklaşım daha iyi bir yaklaşım olabilir. Diziyi, her biri farklı şekilde ele alınan 3 bölüme ayırmaktan bahsediyorsunuz. Bu nedenle, std::partition
'u iki kez ve std::sort
üç kez kullanın. Bence bu daha anlaşılabilir olabilir.
bool isOddMultipleOfThree(int const i)
{
return (i%3==0 && i%2!=0);
}
bool isEvenMultipleOfThree(int const i)
{
return (i%3==0 && i%2==0);
}
int main()
{
int ar[8] = {18 ,5 ,24 ,9 ,12 ,6 ,2, 3};
// split off the first partition
auto firstSplit = std::partition(std::begin(ar),
std::end(ar),
isOddMultipleOfThree);
// sort the first partition
std::sort(std::begin(ar),
firstSplit,
std::less<int>());
// split off end partition
// use a lambda to invert the predicate, because we want the matching
// values pushed to the end
auto secondSplit = std::partition(firstSplit,
std::end(ar),
[](int const i) {
return !isEvenMultipleOfThree(i);
});
// sort middle partition
std::sort(firstSplit,
secondSplit,
std::less<int>());
// sort last partition
std::sort(secondSplit,
std::end(ar),
std::greater<int>());
// print
std::copy(std::begin(ar),
std::end(ar),
std::ostream_iterator<int>(std::cout,
"\n"));
}
Ayrıca
kayda değer, birçok kişi (ben dahil) using namespace std;
düşünün ve std::endl
kötü uygulamalar verilmiştir: Bu kod yukarıdaki gibi aynı çıkışa sahiptir.Üç bölümleri ve ardından her bölüm sıralama içine
da istediğiniz çıktıyı ve aslında almak çıkışını ekleyin. – BoBTFish
Üzgünüm, şimdi ekledim – Khaledooz
Tamam, bu yüzden doğru bölümlenmiş, ancak her bölüm doğru şekilde sıralanmaz. Şimdi bir bakıyorum, sanırım karşılaştırıcınızı daha açık olacak şekilde yeniden yazacağım. – BoBTFish