c ++排序自定义函数

时间:2015-07-03 02:49:10

标签: c++ sorting

我需要能够传入一个要进行排序的变量。我注意到它只会包含它将要排序的类型,所以我想知道是否可以做类似的事情。

例如,我需要它按第3个int对每个包含3个整数的数组进行排序。如果你事先不知道你将要排序的价值,你会如何制作这样的函数?

4 个答案:

答案 0 :(得分:5)

你说"例如我需要它来排序每个包含3个整数的数组,它们的第3个int,"并且在运行时之前你不知道哪个索引(哪一列)是重要的。

如果你能够使用C ++ 11,可以这么简单:

void mysort(vector<vector<int>>& v, int col)
{
    sort(v.begin(), v.end(),
         [col](const vector<int>& a, const vector<int>& b) -> bool
               { return a[col] < b[col]; });
}

如果你被限制在C ++ 98中,你可以做同样的事情,但是你必须编写一个将列作为构造函数参数的函子来代替lambda:

class ColumnSort {
    int col_;
public:
    ColumnSort(int col): col_(col) { }
    bool operator()(const vector& a, const vector& b) const {
        return a[col_] < b[col_];
    }
};

void mysort(vector< vector<int> >& v, int col)
{
    sort(v.begin(), v.end(), ColumnSort(col));
}

最后,如果您想要多列排序,那么仿函数将如下所示,其中cols是要排序的列的有序列表:

class ColumnSort {
    vector<int> cols_;
public:
    ColumnSort(const vector<int>& cols): cols_(cols) { }
    bool operator()(const vector<int>& a, const vector<int>& b) const {
      for (int i = 0; i < cols_.size(); ++i) {
        if (a[cols_[i]] == b[cols_[i]]) continue;
        return a[cols_[i]] < b[cols_[i]];
      }
      return false;
    }
};

答案 1 :(得分:1)

您可以使用自定义比较器构建,其中包含有关自定义排序顺序的信息。你可以这样做。

// Normal sort, except the specified value always comes first
class LessThanWithPreferedValue {
    int n;
public:
    LessThanWithPreferedValue(int v) : n(v) {}

    boolean operator()( int a, int b ) const {
       if( a==n ) { return true ; }
       if( b==n ) { return false ; }
       return a<b;
    }
};

int main() {
  std::vector<int> v = { 2, 3, 4 , 6 ,8 };

  // Normal sort, but with 4 first
  std::sort(v.begin(), v.end(), LessThanWithPreferedValue(4) );
  // v = { 4, 2, 3, 6, 8}

  // Normal sort, but with 8 first
  std::sort(v.begin(), v.end(), LessThanWithPreferedValue(8) );
  // v = { 8, 2, 3, 4, 6}
}

答案 2 :(得分:1)

编写仿函数,它接受参数以确定如何排序。这是一个简单的示例,它使用参数在升序和降序之间切换:

template<typename T>
class ReversibleComparator {
    bool asc;
public:
    ReversibleComparator(bool asc) : asc(asc) {}
    // This function performs the comparison,
    // returning true if a should come before b.
    bool operator()(const T& a, const T& b) {
        if(asc) return a < b;
        else return b < a;
    }
};

当然,您可以根据需要为构造函数提供尽可能多的参数(或多个构造函数),并使逻辑尽可能复杂,尽管它会被调用很多,所以使它真的很复杂可能不会是一个好主意。

调用它的一个例子:

bool asc = true;
if(argc > 1 && argv[1] == string("-d"))
    asc = false;
std::sort(my_list.begin(), my_list.end(), ReversibleComparator(asc));

(另外,这个例子有点人为,因为如果你想要的是颠倒排序,你可以简单地使用rbegin()rend()代替begin()和{{ 1}}分别。)

答案 3 :(得分:-1)

这里我描述了C rtl qsort,但它几乎肯定与c ++变体几乎相同:

sort函数将&#34;比较函数&#34;作为参数。每次调用比较函数时,都会传递两个参数,这两个参数是指向要比较的两个元素的指针。

在强制参数类型后,您可以比较任何您想要的内容。例如,如果元素包含一些带有整数数组的结构,并且您想要比较程序的第一个参数告诉哪个列的第n个项,那么这样的东西将起作用:

int which_index = (int) strtol (argv[1]);

int comparefunc (void *item1, void *item2)
{
     widget *w1, *w2;
     w1 = (widget *) item1;
     w2 = (widget *) item2;

     return w1->myarray[which_index] - w2->myarray[which_index];
}


widget table[1000];
qsort (table, n, sizeof table[0], comparefunc);