我需要能够传入一个要进行排序的变量。我注意到它只会包含它将要排序的类型,所以我想知道是否可以做类似的事情。
例如,我需要它按第3个int对每个包含3个整数的数组进行排序。如果你事先不知道你将要排序的价值,你会如何制作这样的函数?
答案 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);