使用内置函数(或任何其他方法)在C ++中对2D数组进行排序?

时间:2014-01-05 08:43:02

标签: c++ arrays sorting

我有一个像下面这样的2D数组。 (array[5][2]

20  11    
10  20
39  14
29  15
22  23
排序后的

应该如下所示。

10  20
20  11
22  23
29  15
39  14

这意味着应该对数组进行排序,仅比较第一列值。

在Java中,有一个内置的功能来实现这一点。如下。

Arrays.sort(a, new Comparator<Long[]>() {

            @Override
            public int compare(Long[] o1, Long[] o2) {

                Long t1 = o1[1];
                Long p1 = o1[0];
                Long t2 = o2[1];
                Long p2 = o2[0];

                if (t1 == t2) {
                    return (p1 > p2 ? 1 : (p1 == p2 ? 0 : -1));
                } else {
                    return (t1 < t2 ? -1 : 1);
                }

            }
        });

那么有没有C ++内置函数功能来做这些事情或者我怎么能用C ++(最快的实现)呢?

提前致谢:)

8 个答案:

答案 0 :(得分:10)

我之所以提供此功能只是因为std::qsort 比较器是一串三元语句,但如果你盯着它足够长,应该足够清楚:

std::sort

样本运行(显然会有所不同)

#include <iostream>
#include <random>
#include <algorithm>

int main()
{
    int ar[10][2];

    // populate with random data
    std::random_device rd;
    std::default_random_engine rng(rd());
    std::uniform_int_distribution<> dist(1,20);
    std::for_each(std::begin(ar), std::end(ar),
        [&](int (&ar)[2]){ ar[0] = dist(rng); ar[1] = dist(rng); });

    std::cout << "Before Sort..." << '\n';
    std::for_each(std::begin(ar), std::end(ar),
        [](const int(&ar)[2]) { std::cout << ar[0] << ',' << ar[1] << '\n';});

    std::qsort(ar, 10, sizeof(*ar),
        [](const void *arg1, const void *arg2)->int
        {
            int const *lhs = static_cast<int const*>(arg1);
            int const *rhs = static_cast<int const*>(arg2);
            return (lhs[0] < rhs[0]) ? -1
                :  ((rhs[0] < lhs[0]) ? 1
                :  (lhs[1] < rhs[1] ? -1
                :  ((rhs[1] < lhs[1] ? 1 : 0))));
        });

    std::cout << "After Sort..." << '\n';
    std::for_each(std::begin(ar), std::end(ar),
        [](const int(&ar)[2]) { std::cout << ar[0] << ',' << ar[1] << '\n';});

    return 0;
}

注意:这特别使用严格值比较而不是比较器中的减法快捷方式,以避免潜在的下溢问题。如果在受限制的数据空间中这不是​​问题,那么您可以轻松地使该比较器更加简单。

答案 1 :(得分:7)

C和C ++的内置数组非常不灵活,除其他外,它们无法分配。

你最好的选择是来自C ++标准库的'array'类,至少对于内部维度:

array<int, 2> a[5] = { { 20, 11 },
{ 10, 20 },
{ 39, 14 },
{ 29, 15 },
{ 22, 23 } };

sort( a, a + 5 );

编辑:更多解释。

这里我们使用std :: array的属性'&lt;'默认情况下,按字典顺序对它们进行比较,即从第一个元素开始。为了对事物进行不同的排序,我们必须提出一个比较器对象,所以如果你想使用第二列作为排序键,你必须这样做:

auto comp = []( const array<int, 2>& u, const array<int, 2>& v )
      { return u[1] < v[1]; };
sort( a, a + 5, comp );

正如第一条评论所述,sort(a, a+5 ...只是清洁工的一个丑陋的简短形式sort(std::begin(a), std::end(a) ...

答案 2 :(得分:3)

如果可以,请使用Vector和一些结构来容纳两个int

typedef std::pair<int, int> pairType;
std::vector<pairType> vec;

// Initialize vector

std::sort(std::begin(vec), std::end(vec), [](pairType& first, pairType& second)->bool { return first.first < second.first });

答案 3 :(得分:3)

老实说,既然你的第二维中只有两个ints,我会使用一对数组,它们有自己的内置比较函数。使用类似pair<int,int> arr[200]的内容,您可以调用内置排序函数sort(arr, arr + 200),它将按第一个元素排序数组,然后按第二个元素排序。

#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
    // pair of integers
    pair<int, int> arr[1000];

    // fill array with random numbers
    random_device rd;
    mt19937 rng(rd());
    uniform_int_distribution<int> uni(0,1000);
    for(int i = 0; i < 10; i++) {
        // make_pair(x, y) creates a pair with two integers x and y
        arr[i] = make_pair(uni(rng), uni(rng));
    }

    // prints out initial array
    cout << "BEFORE ARRAY..." << endl;
    for(int i = 0; i < 10; i++) {
        // .first and .second call the first and second ints in the pair respectively
        cout << arr[i].first << " " << arr[i].second << endl;
    }
    cout << endl;

    // sort the array by calling built in sort function
    sort(arr, arr + 10);

    // prints out array
    cout << "FINAL ARRAY..." << endl;
    for(int i = 0; i < 10; i++) {
        cout << arr[i].first << " " << arr[i].second << endl;
    }
    cout<<endl;
}

运行此程序时,您会看到数组现已排序:

BEFORE ARRAY...
726 562
916 348
594 6
515 872
976 960
662 169
529 317
789 702
74 255
330 574

FINAL ARRAY...
74 255
330 574
515 872
529 317
594 6
662 169
726 562
789 702
916 348
976 960

注意第二个元素是如何排序的,但是次要的

答案 4 :(得分:2)

首先,如果您提供vector<vector<int>> array,只需使用sort(begin(array), end(array))即可排序,因为vector定义了词典比较功能:http://en.cppreference.com/w/cpp/container/vector/operator_cmp

也就是说,使用vector - vector s:What are the Issues with a vector-of-vectors?有一些缺点,显然不是你想要的。如果int array[5][2]尝试使用sort,则会产生:

  

错误C3863:数组类型'int [2]'不可分配

我们需要交换swap的字节,而不是使用int[2]来交换2 sizeof(*array),而int array[5][2]的字节可以使用qsort完成,如{WhozCraig's answer所示3}},但我们可以改进,使我们的比较器能够处理任何大小的子阵列。给定static const auto SIZE = size(*array); qsort(array, size(array), sizeof(*array), [](const auto lhs, const auto rhs) { const auto first = reinterpret_cast<const int*>(lhs); const auto last = next(first, SIZE); const auto its = mismatch(first, last, reinterpret_cast<const int*>(rhs)); if (its.first == last) { return 0; } else if (*its.first < *its.second) { return -1; } else { return 1; }}); 或任何所需的维度,我们可以写:

array

快速注释this.props.location.query不应该用作变量名称,因为它定义了标准类型,您可以在此处找到一个示例:http://ideone.com/87AoIr

答案 5 :(得分:1)

如果最终容器无关紧要,那么使用地图怎么样?

#include<map>

std::map<int, int> m;

for(std::size_t i = 0; i < 5; ++i )
    m[array[i][0]] = array[i][1] ;

您现在可以将m复制回array

std::size_t  i=0;
for(const auto& x:m)
{   
    array[i][0] = x.first ;
    array[i++][1] = x.second ;
}

答案 6 :(得分:1)

及时对2D数组进行排序的最快方法(仅使用列)。 。 .Will会花费你参考地点......否则,其他方式都会涉及大量的行复制。 。虽然(C ++的移动操作可以缓解这一点)

你会创建一个指向2D数组的新指针数组......然后对指针进行排序......

否则,我之前的所有其他答案似乎都很好。但我建议你使用std :: array。

答案 7 :(得分:0)

我们可以使用 C++ 中的内置排序函数简单地在行或列的基础上使用排序。 我们只需要传递带有适当参数的比较函数即可。

这是一个按列对二维数组进行排序的示例。

#include<iostream>
#include<algorithm>
using namespace std;

bool compare(int *a, int *b){
    // sorting on basis of 2nd column
    return a[1] < b[1];
}

void sorting(int **arr,int n){
    //calling in built sort
    sort(arr, arr + n, compare);
    // printing after sorting 
    cout<<"---------After Sorting---------"<<endl;
    for(int i = 0; i < n; i++){
        cout<<arr[i][0]<<" "<<arr[i][1]<<endl;
    }
}

int main(){
    int **arr, i, n;
    cout<<"Enter the size of array  : ";
    cin>>n;
    //array of size arr[n][2]; 
    arr = new int*[n];
    for(i = 0; i < n; i++){
        arr[i] = new int[2];
    }
    
    for(int i = 0; i < n; i++){
        cin>>arr[i][0];
        cin>>arr[i][1];
    }
    
    sorting(arr, n);
    return 0;
}