如何使用C ++制作双排序整数数组?

时间:2011-11-25 09:52:13

标签: c++ arrays sorting

我有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);

5 个答案:

答案 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

完成了!