C ++ - 通过包含的对象属性对多维向量进行排序

时间:2010-08-05 10:09:31

标签: c++ arrays object vector sorting

我有一个二维对象数组(包含GridCell实例的2D向量),如下所示:

typedef vector<GridCell> CellArray;
typedef vector<CellArray> TwoDCellArray;
TwoDCellArray CellArr2D;

我目前正在绘制所有这样的单元格:

for (int i = 0; i < rows; i++){
    for (int j = 0; j < cols; j++){
        CellArr2D[i][j].draw()
    }
}

但是,我有一个深度问题,我应该根据它的大小绘制实例(大小属性,CellArr2D [i] [j] .size)。

如何对此数组进行排序而不更改其i,j值?将所有对象复制到辅助数组并对其进行排序? 并且更加重要,因此这篇文章......我如何通过它包含的对象属性对数组(Vector)进行排序?

提前致谢。

3 个答案:

答案 0 :(得分:3)

创建对(i,j)的向量,并按size属性对其进行排序。

typedef std::pair<int, int> int_pair_t;
typedef std::vector< int_pair_t > size_index_t;

namespace {
struct sort_helper {
    sort_helper( const TwoDCellArray& arr ) : arr_(arr) {}      
    bool operator()( const int_pair_t& ind1, const int_pair_t& ind2 ) { 
      return arr_[ind1.first][ind1.second].size > arr_[ind2.first][ind2.second].size; 
    }
private:
    const TwoDCellArray& arr_;
};

struct draw_helper {
    draw_helper( TwoDCellArray& arr ) : arr_(arr) {}        
    void operator()( const int_pair_t& ind ) { 
        arr_[ind.first][ind.second].draw();
    }
private:
    TwoDCellArray& arr_;
};
}

void some_func()
{
    // initialize helper array of indices
    size_index_t index;
    index.reserve( rows*cols );
    for ( int i = 0; i < rows*cols; ++i )
        index.push_back( make_pair( i/cols%rows, i%cols ) );

    // sort according to the `size` field
    std::sort( index.begin(), index.end(), sort_helper( CellArr2D ) );

    // draw
    std::for_each( index.begin(), index.end(), draw_helper( CellArr2D ) );
}

答案 1 :(得分:1)

使用std :: sort并提供自定义比较函数对象,以按用户定义的属性或其他关系进行排序。

至于它应该如何排序,如果你想对它进行排序而不是更改它,那么你将不得不复制数组。执行此操作的最佳方法是将GridCell存储在堆上,并在向量中存储智能指针。这样,对它们进行排序和复制将减少开销。

答案 2 :(得分:0)

您可以将引用放在辅助数组中并对其进行排序:

struct CellRef
{
  CellRef(GridCell& cell) : m_c(cell) {}
  bool operator<(const CellRef& r) const { return m_c.size < r.m_c.size; }
  GridCell& data() { return m_c; }
private:
  GridCell& m_c;
};

vector<CellRef> refs;
for (int i = 0; i < rows; i++){
    for (int j = 0; j < cols; j++){
        refs.push_back(CellArr2D[i][j]);
    }
}
std::sort(refs.begin(), refs.end());
for(vector<CellRef>::iterator it=refs.begin(), end=refs.end(); it!=end; ++it)
  it->data().draw();