按多个因素对表进行排序

时间:2014-07-17 20:23:47

标签: c++ sorting

所以我遇到的情况是我必须编写一个类来对元素表进行排序。我只想对列进行排序,但我想进行多级排序,例如

a 2
b 1
b 2
a 1

第一个排序将在第一列上,最终结束如此

a 2
a 1
b 1
b 2

现在我想对第二列进行排序而不破坏第一列排序已经如此

a 1
a 2
b 1
b 2

我的想法是,对于每个排序级别,我都会跟踪需要排序的范围。所以在初始排序之前我的范围是这样的: range = 0..3然后我的下一个级别是range=0..1,2..3。我不确定这是否会非常有效,所以我想就任何其他方式获得意见。

编辑:我需要为每列使用自定义比较器获取任意数量的列

2 个答案:

答案 0 :(得分:4)

您可以将每行存储在std::pair<char, int>中,将其放在std::vector<std::pair<char, int>>中,然后使用std::sort功能为您提供所需的排序。您不必编写自己的任何类或算法。

std::vector<std::pair<char, int>> table;

// read data into `table`
....

// sort the table
std::sort(table.begin(), table.end());

// print out contents
for (const auto& p : table)
{
  std::cout << p.first << " " << p.last << "\n";
}

如果您遇到旧的C ++实现,可以使用std::tuple(或std::tr1::tupleboost::tuple来推广到更多列。 tuples进行词典比较,其工作方式与pair相同。如果需要不同的排序,可以将自己的比较函数作为第3个参数传递给std::sort

答案 1 :(得分:0)

这是一个例子

#include <iostream>
#include <algorithm>
#include <iterator>
#include <utility>

int main() 
{
    std::pair<char, int> a[] = 
    { 
        { 'a', 2 },
        { 'b', 1 },
        { 'b', 2 },
        { 'a', 1 }
    };

    for ( const auto &p : a )
    {
        std::cout << p.first << '\t' << p.second << std::endl;
    }

    std::cout << std::endl;

    std::sort( std::begin( a ), std::end( a ) );

    for ( const auto &p : a )
    {
        std::cout << p.first << '\t' << p.second << std::endl;
    }

    return 0;
}

输出

a   2
b   1
b   2
a   1

a   1
a   2
b   1
b   2

而不是std::pair,您可以将std::tuple用于多个列。例如

#include <iostream>
#include <algorithm>
#include <iterator>
#include <tuple>

int main() 
{
    std::tuple<char, int, bool> a[] = 
    { 
        std::make_tuple( 'a', 2, true ),
        std::make_tuple( 'b', 1, false ),
        std::make_tuple( 'b', 2, true ),
        std::make_tuple( 'a', 1, true ),
        std::make_tuple( 'a', 2, false ),
        std::make_tuple( 'a', 1, false )
    };

    for ( const auto &t : a )
    {
        std::cout << std::get<0>( t ) << '\t' 
                  << std::get<1>( t ) << '\t'
                  << std::get<2>( t ) << std::endl;
    }

    std::cout << std::endl;

    std::sort( std::begin( a ), std::end( a ) );

    for ( const auto &t : a )
    {
        std::cout << std::get<0>( t ) << '\t' 
                  << std::get<1>( t ) << '\t'
                  << std::get<2>( t ) << std::endl;
    }

    return 0;
}

输出

a   2   1
b   1   0
b   2   1
a   1   1
a   2   0
a   1   0

a   1   0
a   1   1
a   2   0
a   2   1
b   1   0
b   2   1

如果必须对具有不同数据成员的结构数组进行排序,则可以从这些数据成员构建元组,并在谓词std::sort中使用它。