使用内置函数(或任何其他方法)在C++中对2D数组进行排序
Sort a 2D array in C++ using built in functions(or any other method)?
我有一个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++(最快的实现)中做到这一点?
提前感谢:)
我之所以提供这个功能,只是因为它是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;
}
样本运行(很明显,您的情况会有所不同)
Before Sort...
2,11
18,4
20,20
14,6
8,10
17,8
14,14
3,10
20,14
19,19
After Sort...
2,11
3,10
8,10
14,6
14,14
17,8
18,4
19,19
20,14
20,20
注意:这特别使用了严格的值比较,而不是比较器中的减法捷径,以避免潜在的下溢问题。如果在受限的数据空间中这不是问题,那么可以很容易地使比较器变得更简单。
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的属性,该属性为'<'默认情况下,按字典顺序对它们进行比较,即从第一个元素开始。为了对事物进行不同的排序,我们必须想出一个comparator对象,所以如果你想使用第二列作为排序键,你必须这样做:
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) ...
的一个丑陋的缩写
老实说,由于第二维度中只有两个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
请注意,第二个元素也是如何排序的,但次要于
首先,如果给定vector<vector<int>> array
,则只需使用:sort(begin(array), end(array))
即可对其进行排序,因为vector
定义了字典比较函数:http://en.cppreference.com/w/cpp/container/vector/operator_cmp
也就是说,使用vector
-of-vector
s有缺点:向量中的向量有什么问题?这显然不是你想要的。给定int array[5][2]
尝试使用sort
将产生:
错误C3863:数组类型"int[2]"不可分配
我们不需要使用swap
来交换2个int[2]
,而只需要交换sizeof(*array)
的字节,正如WhozCraig的回答所建议的那样,这可以使用qsort
来实现,但我们可以改进这一点,使我们的比较器能够处理任何大小的子阵列。给定int array[5][2]
或任何需要的尺寸,我们可以写:
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
不应用作变量名,因为它定义了标准类型,通过此更改,您可以在此处找到一个示例:http://ideone.com/87AoIr
如果可以的话,使用带有一些结构的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 });
我们可以使用c++中内置的排序函数,简单地在行或列的基础上使用排序。我们只需要传递带有适当参数的compare函数。
以下是按列对2D数组进行排序的示例。
#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;
}
对2D数组进行时间排序的最快方法(仅使用列)。将花费您的参考位置。。。否则,所有其他方式都将涉及大量的行复制。尽管(C++的移动操作可能会缓冲这一点)
你可以创建一个指向2D数组的新指针数组。。。然后对指针进行排序。。。
除此之外,在我之前的所有其他答案似乎都很好。但我建议您使用std::array。
如果结束容器无关紧要,那么使用映射怎么样?
#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 ;
}
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 在C++中对T*类型执行std::move的意外行为
- 如何在信号处理程序和普通函数中对全局变量进行互斥读写操作
- 试图在c++中对数字列表进行排序
- 为什么在C++20中对lambdas使用"std::bind_front"
- 在 c++ 中对类中的 c 字符串动态数组进行排序的最佳方法是什么?
- 为什么在C++中对链表这样做?(像堆叠一样处理它们)
- 如何在 CMake 中对目标依赖项进行分组?
- 在 c++ 中对单个排序数组中的 2 个未排序数组进行排序
- 在 C++20 中是否不再允许在 std 中对程序定义类型的函数模板进行专用化?
- 在 c++ 中对字符串使用复制函数时打印的垃圾值
- 如何在BST树中对数字的乘积收费?
- 在 C++ 中对 PyObject 调用"+="
- 在 c++ 中对字符串进行操作的关系运算符无法按预期工作
- QT C++中对全局变量的未定义引用
- 我想在 c++ 中对单向链表进行冒泡排序,但我一直面临左值错误,无法解决它
- 使用 C++在 OpenGL 中对 3D 多边形进行纹理处理
- 如何在数组 c++ 中对字符串进行排序
- 如何在C++中对OpenCV垫的小数进行四舍五入?
- 在C++中对结构向量进行排序时出现问题