您好我已尝试在此特殊情况下对数组进行排序
a)可以被3整除的奇数必须先上升
b)即使是可以被3整除的数字也必须最后下降
c)不能被3整除的数字按升序排序
这是我的代码
#include<algorithm>
#include<iostream>
using namespace std ;
bool cmp(int b,int a){
if((b%2 && b%3==0) && (a%2==0 || a%3 || b>a) )
return true ;
if((a%2==0 && a%3==0) && (b%2 || b%3) )
return true ;
return false ;
}
int main(){
int ar[8]={18 ,5 ,24 ,9 ,12 ,6 ,2, 3};
sort(ar,ar+8,cmp);
for(int i=0;i<8;i++)
cout<<ar[i]<<endl ;
return 0;
}
我的输出
9 3 五 2 18 24 12 6
例外
3 9 2 5 24 18 12 6
所以现在数组被分为3个块,但没有按照我上面提到的特殊情况进行排序
答案 0 :(得分:1)
由于您的比较功能非常复杂,我已经非常详细地重写了它,因此可以单独检查每种可能的情况。我还分成了一个不同的函数,决定每个元素输入的哪个分区。
>>> sentence = "there is an accident along uhuru highway"
>>> a = re.search(r'.* ([\w\s\d\-\_]+) highway', sentence)
>>> print(a.group(1))
>>> uhuru
输出:
#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"));
}
请记住,你的比较器必须引出一个Strict Weak Ordering,我认为这样做,但它比通常用于排序的技术要复杂一些。
始终尽可能将代码编写为 ,而不是简短。如果您有一些复杂的逻辑,请将其拆分,将零件移到函数中,并添加大量注释。请记住,其他人必须阅读并理解它,包括6个月内的自己。
可能更好的方法是拆分排序。你真的在谈论将数组拆分为3个分区,每个分区的处理方式不同。因此,使用std::partition
两次,std::sort
三次。我认为这可能更容易理解。此代码具有与上述完全相同的输出:
$ ./SO
3
9
2
5
24
18
12
6
另外值得一提的是,很多人(包括我自己)认为using namespace std;
和std::endl
都是不良做法。
答案 1 :(得分:1)
首先使用std::partition
&#34;拆分&#34;将您的数组分成三个分区,然后对每个分区进行排序,您将获得类似
#include <iostream>
#include <array>
#include <algorithm>
#include <functional>
int main()
{
std::array<int, 8> array = {{ 18 ,5 ,24 ,9 ,12 ,6 ,2, 3 }};
std::cout << "Before first partitioning: ";
for (auto const value : array)
std::cout << value << ' ';
std::cout << '\n';
// First partition putting all odd number even divisible by three first
auto second_start = std::partition(std::begin(array), std::end(array), [](int const& value) {
return (value % 2 != 0 && value % 3 == 0);
});
std::cout << "Before second partitioning: ";
for (auto const value : array)
std::cout << value << ' ';
std::cout << '\n';
// Then partition putting all even number even divisible by three first
auto third_start = std::partition(second_start, std::end(array), [](int const& value) {
return !(value % 2 == 0 && value % 3 == 0);
});
std::cout << "Before sorting: ";
for (auto const value : array)
std::cout << value << ' ';
std::cout << '\n';
std::sort(std::begin(array), second_start, std::less<int>());
std::sort(second_start, third_start, std::less<int>());
std::sort(third_start, std::end(array), std::greater<int>());
std::cout << "After sorting: ";
for (auto const value : array)
std::cout << value << ' ';
std::cout << '\n';
}
输出
Before first partitioning: 18 5 24 9 12 6 2 3 Before second partitioning: 3 9 24 5 12 6 2 18 Before sorting: 3 9 2 5 12 6 24 18 After sorting: 3 9 2 5 24 18 12 6
分娩后的输出与您的预期一致。
在&#34;操作&#34;。
中查看here这是更多的工作,但也保证按预期行事。
答案 2 :(得分:1)
这个简单的比较功能对我有用:
bool cmp(int lhs, int rhs){
bool lhs_div_3 = lhs % 3 == 0;
bool rhs_div_3 = rhs % 3 == 0;
bool lhs_odd = lhs & 1;
bool rhs_odd = rhs & 1;
if (lhs_div_3 && lhs_odd) // lhs in class a)
if (rhs_div_3 && rhs_odd)
return lhs < rhs;
else
return true;
if (!lhs_div_3) // lhs in class c)
if (!rhs_div_3)
return lhs < rhs;
else
return !rhs_odd;
// else lhs in class b)
if (rhs_div_3 && !rhs_odd)
return rhs < lhs;
return false;
}
但是如果您有大型阵列并且关心性能,您应该首先对数据进行分区,然后按照其他人的建议对每个3个部分进行独立排序(以避免这种复杂的,即慢速比较功能)。
答案 3 :(得分:1)
我会为{partition1, partition2, order}
构建一个元组:
auto helper(int i)
{
bool isEven = i % 2 == 0;
bool isMul3 = i % 3 == 0;
return std::make_tuple(!(!isEven && isMul3), // partition 1
isEven && isMul3, // partition2
isEven && isMul3 ? -i : i); // order
}
bool cmp(int lhs, int rhs){
return helper(lhs) < helper(rhs);
}