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方式。
您应该使用
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指针比较"函数"(即您创建的类实例)不同,它具有
不幸的是,在C语言中,除了创建一个全局变量之外,您不能用其他方法来实现这一点。