Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 以特定方式对数组排序_C++_Arrays_Sorting - Fatal编程技术网

C++ 以特定方式对数组排序

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)

您好,我已尝试在这种特殊情况下对数组进行排序

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;
}
#包括
#包括
使用名称空间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);
}