我有3列整数数组,其最后2个元素用于排序。例如
10 0 1
11 0 2
12 1 2
13 0 1
我希望他们成为:
10 0 1
13 0 1
11 0 2
12 1 2
首先根据第2列对数组进行排序,然后根据第3列进行排序。
我有超过3000行,所以我也需要快速的东西。你怎么能用c ++做到这一点?
注意:将使用以下模板动态分配数组:
template <typename T>
T **AllocateDynamic2DArray(int nRows, int nCols){
T **dynamicArray;
dynamicArray = new T*[nRows];
for( int i = 0 ; i < nRows ; i++ ){
dynamicArray[i] = new T[nCols];
for ( int j=0; j<nCols;j++){
dynamicArray[i][j]= 0;
}
}
return dynamicArray;
}
在main中,
int ** lineFilter = AllocateDynamic2DArray(2 * numberOfLines,3);
答案 0 :(得分:4)
你可以使用std::sort()
;但是,由于您的数组是2D,这很复杂。
通常,std::sort()
不能吃二维数组;你必须创建一个类来围绕编译器警告和投诉:
#include <iostream>
#include <algorithm>
int data[4][3] = {
{10,0,1},
{11,0,2},
{12,1,2},
{13,0,1}
};
struct row_t { // our type alias for sorting; we know this is compatible with the rows in data
int data[3];
bool operator<(const row_t& rhs) const {
return (data[1]<rhs.data[1]) || ((data[1]==rhs.data[1]) && (data[2]<rhs.data[2]));
}
};
int main() {
std::sort((row_t*)data,(row_t*)(data+4));
for(int i=0; i<4; i++)
std::cout << i << '=' << data[i][0] << ',' << data[i][1] << ',' << data[i][2] << ';' << std::endl;
return 0;
}
如果您使用std::vector
来保存真正属于row_t
类型的商品,则会变得更容易。向量是动态调整大小和可排序的。
答案 1 :(得分:2)
我认为这应该有效:
template<typename T>
struct compareRows {
bool operator() (T * const & a, T * const & b) {
if (a[1] == b[1])
return a[2] < b[2];
else
return a[1] < b[1];
}
};
std::sort(dynamicArray, dynamicArray+nrows, compareRows<int>());
使用仿函数实现行之间的比较。排序将指向每行的开头并根据行的内容交换它们。行将保留在内存中的相同位置。
答案 2 :(得分:1)
好的,OP有一个三列整数数组,排序不是很简单,因为你不能分配数组。
一个选项是拥有结构数组,其中结构包含每列的一个元素,编写自定义比较例程并使用std::sort
。
另一种选择是假装我们有这样一个结构数组并使用reinterpret_cast
的邪恶,如下所示:
#include <algorithm>
#include <iostream>
struct elt_t
{
int e0;
int e1;
int e2;
};
int
compare (const elt_t &a, const elt_t &b)
{
if (a.e1 == b.e1)
return a.e2 < b.e2;
else
return a.e1 < b.e1;
}
int a [10][3] =
{
{ 10, 0, 1 },
{ 11, 0, 2 },
{ 12, 1, 2 },
{ 13, 0, 1 }
};
int
main ()
{
std::sort (reinterpret_cast<elt_t *>(&a[0]),
reinterpret_cast<elt_t *>(&a[4]), compare);
int i, j;
for (i = 0; i < 4; ++i)
std::cout << a [i][0] << ", " << a [i][1] << ", " << a [i][2] << std::endl;
return 0;
}
当然,这是否符合标准是值得商榷的:)
修改强>
通过动态分配对矩阵的附加要求,您可以使用std::vector
数组或std::vector
的向量:
#include <algorithm>
#include <iostream>
#include <vector>
int
compare (const std::vector<int> &a, const std::vector<int> &b)
{
if (a[1] == b[1])
return a[2] < b[2];
else
return a[1] < b[1];
}
std::vector<int> *
make_vec (unsigned int r, unsigned int c)
{
std::vector<int> *v = new std::vector<int> [r];
/* Don't care for column count for the purposes of the example. */
v [0].push_back (10); v [0].push_back (0); v [0].push_back (1);
v [1].push_back (11); v [1].push_back (0); v [1].push_back (2);
v [2].push_back (12); v [2].push_back (1); v [2].push_back (2);
v [3].push_back (13); v [3].push_back (0); v [3].push_back (1);
return v;
}
int
main ()
{
std::vector<int> *v = make_vec (4, 3);
std::sort (&v[0], &v[4], compare);
int i, j;
for (i = 0; i < 4; ++i)
std::cout << v[i][0] << ", " << v [i][1] << ", " << v [i][2] << std::endl;
delete [] v;
return 0;
}
答案 3 :(得分:0)
将其用于第二列,然后用于第三列。现在它适用于单个暗淡阵列
int *toplace(int *start, int *end)
{
int *i = start+1, *j= end-1;
while(i<=j)
{
while(*i<=*start && i<=j) {i++;}
while(*j>=*start && i<=j) {j--;}
if (i<j) std::swap(*i++,*j--);
}
std::swap(*start,*(i-1));
return i-1;
}
void quicksort(int *start, int *end)
{
if (start >= end) return;
int *temp = start;
temp = toplace(start,end);
quicksort(start,temp);
quicksort(temp+1,end);
}
答案 4 :(得分:-1)
您可以使用冒泡排序算法(http://en.wikipedia.org/wiki/Bubble_sort)执行此操作。
基本上遍历所有记录,将当前记录与下一记录进行比较。如果当前记录的第二列较高,则交换这些记录。如果当前记录的第二列相等但第三列较高,则交换。
继续迭代,直到不再进行掉期。
使用您的示例:
10 0 1
11 0 2
12 1 2(与下一个交换)
13 0 1
10 0 1
11 0 2(与下一个交换)
13 0 1
12 1 2
10 0 1
13 0 1
11 0 2
12 1 2
完成了!