2016-11-17 38 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