C++ 以特定方式对数组排序
您好,我已尝试在这种特殊情况下对数组进行排序 a) 可被3整除的奇数必须先升后降 b) 可被3整除的偶数必须是最后一个 c) 不能被3整除的数字按升序排序 这是我的密码C++ 以特定方式对数组排序,c++,arrays,sorting,C++,Arrays,Sorting,您好,我已尝试在这种特殊情况下对数组进行排序 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)
#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;
}
#包括
#包括
使用名称空间std;
布尔cmp(整数b,整数a){
如果((b%2和&b%3==0)和((a%2==0 | a%3 | b>a))
返回true;
如果((a%2==0&&a%3==0)&&(b%2 | | b%3))
返回true;
返回false;
}
int main(){
int ar[8]={18,5,24,9,12,6,2,3};
排序(ar,ar+8,cmp);
对于(int i=0;i,由于比较函数非常复杂,所以我将其重写得非常详细,因此可以分别检查每个可能的情况。我还将每个元素进入输出的哪个分区的决定分离到不同的函数中
#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"));
}
记住,你的比较器必须诱导a,我想这是可以的,但它比通常用于排序的方法要复杂一些
始终尽可能清晰地编写代码,而不是尽可能短。如果您有一些复杂的逻辑,请将其分解,将部分移到函数中,并添加大量注释。记住,其他人必须阅读和理解它,包括您自己,在6个月内
更好的方法可能是拆分排序。您实际上是在谈论将阵列拆分为3个分区,每个分区的处理方式不同。因此,请使用两次,三次。我认为这可能更容易理解。此代码的输出与上面的代码完全相同:
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"));
}
bool isOddMultipleOfThree(int const i)
{
返回(i%3==0&&i%2!=0);
}
布尔是三个整数的倍数(整数常数i)
{
返回(i%3==0&&i%2==0);
}
int main()
{
int ar[8]={18,5,24,9,12,6,2,3};
//分离第一个分区
自动firstSplit=std::partition(std::begin(ar),
标准::结束(ar),
isOddMultipleOfThree);
//对第一个分区进行排序
标准::排序(标准::开始(ar),
第一次分裂,
std::less());
//分离式端部隔板
//使用lambda反转谓词,因为我们需要匹配
//将值推到最后
auto secondSplit=std::partition(第一次拆分,
标准::结束(ar),
[](int const i){
返回!是三(i)的七倍;
});
//排序中间分区
标准::排序(第一次拆分,
第二次分裂,
std::less());
//对最后一个分区排序
标准::排序(第二次拆分,
标准::结束(ar),
std::greater());
//印刷品
标准::复制(标准::开始(ar),
标准::结束(ar),
std::ostream_迭代器(std::cout,
“\n”);
}
同样值得一提的是,很多人(包括我自己)考虑到并不是很好的实践。因为你的比较函数是相当复杂的,所以我已经非常详细地重写了它,所以每个可能的情况都可以单独检查。
#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"));
}
记住,你的比较器必须诱导a,我想这是可以的,但它比通常用于排序的方法要复杂一些
始终尽可能清晰地编写代码,而不是尽可能短。如果您有一些复杂的逻辑,请将其分解,将部分移到函数中,并添加大量注释。记住,其他人必须阅读和理解它,包括您自己,在6个月内
更好的方法可能是拆分排序。您实际上是在谈论将阵列拆分为3个分区,每个分区的处理方式不同。因此,请使用两次,三次。我认为这可能更容易理解。此代码的输出与上面的代码完全相同:
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"));
}
bool isOddMultipleOfThree(int const i)
{
返回(i%3==0&&i%2!=0);
}
布尔是三个整数的倍数(整数常数i)
{
返回(i%3==0&&i%2==0);
}
int main()
{
int ar[8]={18,5,24,9,12,6,2,3};
//分离第一个分区
自动firstSplit=std::partition(std::begin(ar),
标准::结束(ar),
isOddMultipleOfThree);
//对第一个分区进行排序
标准::排序(标准::开始(ar),
第一次分裂,
std::less());
//分离式端部隔板
//使用lambda反转谓词,因为我们需要匹配
//将值推到最后
auto secondSplit=std::partition(第一次拆分,
标准::结束(ar),
[](int const i){
返回!是三(i)的七倍;
});
//排序中间分区
标准::排序(第一次拆分,
第二次分裂,
std::less());
//对最后一个分区排序
标准::排序(第二次拆分,
标准::结束(ar),
std::greater());
//印刷品
标准::复制(标准::开始(ar),
标准::结束(ar),
std::ostream_迭代器(std::cout,
“\n”);
}
另外,很多人(包括我自己)都认为是不好的做法。
< P>使用第一个“拆分”数组到三个分区,然后对每个分区进行排序,你会得到类似的东西。
#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';
}
#包括
#包括在“行动”中
这需要更多的工作,但也保证按预期运行。使用先将阵列“拆分”为三个分区,然后对每个分区进行排序,您将得到如下结果
#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';
}
#包括
#包括在“行动”中
这需要更多的工作,但也保证按照预期的方式工作。这个简单的比较函数可以工作
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);
}