2016-11-17 24 views
2

this问题排序通过柱二维阵列,我们看到一个很好的解释由每个向量的第一元件和第二示例通过每个载体和排序它的元件将会排序矢量如何。
使用STL

我知道数组不是 C++的一级公民 STL的权力用户,但我喜欢阵列(就像安德烈Alexandrescu)。

所以,让我们考虑代码:

typedef int arr2D[3]; 

arr2D array2D[3] = { { 1, 4, 3 }, 
        { 9, 2, 5 }, 
        { 7, 6, 8 } }; 

std::sort(begin(array2D[2]), end(array2D[2]), greater<>()); 

这样做的结果是,由降序排列,这样排序 array2D最后行:

1 4 3 
9 2 5 
8 7 6 <- last row by descending order 

不过,我想要的是按照降序排列最后的array2D列,如下所示:

1 4 8 
9 2 5 
7 6 3 
    ^
    └--- last column by descending order 

使用普通array S(未载体)和std::sort,有人可以帮我吗?

谢谢

+0

可惜你不能“列”使用'的std :: sort'排序。你可以将它们提取到一个单独的数组(或向量)中(所以'newArray [0]'对应于'array2D [0] [2]'等),对它们进行排序并将排序后的值写回到数组中。 –

+0

在排序之前和之后,您将不得不调换矩阵。 – Jonas

+0

一些程序员老兄和乔纳斯:我认为你们两个都一样,但在我读到你们的意见之前,我认为我错了。现在我确信'std :: sort'只能应用于连续的数据结构。 – user7140484

回答

3

你可以写一个自定义的迭代器,该迭代在特定的列中的元素,在每一行。例如:

template<class Arr> 
using sub_array_t = std::remove_pointer_t<std::decay_t<Arr>>; 

template<class Arr> 
using column_iterator_base = std::iterator<std::random_access_iterator_tag, sub_array_t<sub_array_t<Arr>>>; 

template<std::size_t col_index, class Arr> 
struct column_iterator : column_iterator_base<Arr> 
{ 
    using parent = column_iterator_base<Arr>; 
    using value_type = typename parent::value_type; 
    using difference_type = typename parent::difference_type; 
    using sub_array = sub_array_t<Arr>; 

    Arr* arr; 
    sub_array* row; 

    column_iterator(Arr* arr)     : arr(arr), row(*arr) {} 
    column_iterator(Arr* arr, sub_array* row) : arr(arr), row(row) {} 

    column_iterator begin() {return {arr};} 
    column_iterator end() {return {arr, std::end(*arr)};} 

    column_iterator& operator+=(difference_type rhs) {row += rhs; return *this;} 
    column_iterator& operator-=(difference_type rhs) {row -= rhs; return *this;} 
    value_type& operator*() const {return (*row)[col_index];} 
    value_type* operator->() const {return (*row) + col_index;} 
    value_type& operator[](difference_type rhs) const {return row[rhs][col_index];} 

    column_iterator& operator++() {++row; return *this;} 
    column_iterator& operator--() {--row; return *this;} 
    column_iterator operator++(int) {column_iterator tmp(arr, row); ++row; return tmp;} 
    column_iterator operator--(int) {column_iterator tmp(arr, row); --row; return tmp;} 

    difference_type operator-(const column_iterator& rhs) const {return row-rhs.row;} 
    column_iterator operator+(difference_type rhs) const {return column_iterator(arr, row+rhs);} 
    column_iterator operator-(difference_type rhs) const {return column_iterator(arr, row-rhs);} 
    friend inline column_iterator operator+(difference_type lhs, const column_iterator& rhs) 
    {return column_iterator(rhs.arr, lhs+rhs.row);} 
    friend inline column_iterator operator-(difference_type lhs, const column_iterator& rhs) 
    {return column_iterator(rhs.arr, lhs-rhs.row);} 

    bool operator==(const column_iterator& rhs) const {return row == rhs.row;} 
    bool operator!=(const column_iterator& rhs) const {return row != rhs.row;} 
    bool operator> (const column_iterator& rhs) const {return row > rhs.row;} 
    bool operator< (const column_iterator& rhs) const {return row < rhs.row;} 
    bool operator>=(const column_iterator& rhs) const {return row >= rhs.row;} 
    bool operator<=(const column_iterator& rhs) const {return row <= rhs.row;} 
}; 

template<std::size_t col_index, class Arr> 
auto make_column_iterator(Arr* arr) 
{ 
    return column_iterator<col_index, Arr>(arr); 
} 


int main() 
{ 
    // array2D = ... 
    auto foo = make_column_iterator<1>(&array2D); 
    std::sort(foo.begin(), foo.end()); 
} 

很多自定义迭代器的样板可以通过使用boost来避免。

注:这是快速写入,并可能包含错误和不必要的复杂代码。

+0

我很感谢你的努力,但正如你所说,它有错误,我不幸无法纠正。 – user7140484

+0

@ user7140484它行为不符合您的预期? – user2079303

+0

代码甚至没有编译,我无法理解错误。 – user7140484