关于c ++:Qsort基于c-string中的列?

Qsort based on a column in a c-string?

类项目涉及对字符串数组进行排序,每个字符串包含相同数量的列,如:

1
2
3
4
5
Cartwright   Wendy    93
Williamson   Mark     81
Thompson     Mark     100
Anderson     John     76
Turner       Dennis   56

程序接受要排序的列的命令行参数,并应打印出未修改的已排序字符串。

我想使用strtok将每个字符串的副本分解成列,并为每一行创建如下结构:

1
2
3
4
struct line {
    char * line;
    char column_to_sort_on[MAX_COLUMN];
}

我的问题在于qsort将比较函数指针作为参数。如果我理解正确,比较函数必须取两个常量void指针指向要排序的项,并返回一个int。这意味着我不能将指向结构的指针传递给比较函数,因为这不是qsort将要排序的内容。我无法将列号传递给比较函数,因为它只能接受两个参数。如何绕过这个问题,根据特定的列对这些字符串进行排序?

编辑:排序仅限于qsort或我自己的,如果我真的想要的话。给我选择,我选择qsort。:)

编辑2:共识是要么对列号使用全局变量,要么只使用qsort对结构数组排序。我没有想到只对结构进行排序,并使用其中的指针打印出原始字符串。我想这就是我要做的。谢谢大家的帮助!


您可以这样传递结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
struct line {
    char * line;
    char column_to_sort_on[MAX_COLUMN];
}
...

line*  Lines[max_lines]; // here you store the structs

int
cmp_lines( const void *elem1, const void *elem2 )
{
    line*  line1 = *(line**)elem1;
    line*  line2 = *(line**)elem2;
    // do the comparisons
}

qsort(Lines, max_lines, sizeof(line*), cmp_lines);


不同的比较器函数,都采用整个结构,但每个函数只使用一列进行比较。


假设您不限于使用Q排序,可以使用STD::排序,用存储列号的函子对象。如果必须使用qsort,一个快速而肮脏的解决方案是将列号存储在全局变量中,并在comparisson函数中使用该列号。


C++还是C?基于你的标签,我假设它是C++。让我们试试STL方式。

您应该使用std::sort而不是qsortstd::sort不仅可以接受函数指针(与它的C选项相比),还可以接受任何可以作为函数调用的对象。您可能知道类实例可以作为带有operator()的函数来调用。然后解决方案很简单:创建一个"functor"类,在构造时创建不同的函数。排序调用将如下所示:

1
std::sort(array, array+size, comparator(2 /* sort by column #2 */));

functor类有效地创建了一个所谓的"闭包":一个动态创建的函数对象,它具有局部变量,但不与以这种方式创建的其他函数对象共享。如下所示:

1
2
3
4
5
6
class comparator{
  private: unsigned int field_n;
  public: comparator(unsigned int _field_n) : field_n(_field_n) {};
  public: int operator () (char const *  lhs, char const * rhs)
       { /* compare here fields with index field_n */ };
};

请注意,与void指针比较"函数"(即您创建的类实例)不同,它具有char *参数,因此您不必为类型转换而烦恼。

不幸的是,在C语言中,除了创建一个全局变量之外,您不能用其他方法来实现这一点。