按字母顺序排序字符数组,然后按长度排序
Sorting array of chars alphabetically then by length
>我有一个结构数组,我可以在其中跟踪每个唯一单词在给定文本中出现的次数:
struct List {
char word[20];
int repeat;
};
现在我需要对此进行排序:
as 6
a 1
appetite 1
angry 1
are 2
and 4
...
对此:
a 1
as 6
and 4
are 2
angry 1
appetite 1
...
(按字母顺序,我的意思是仅通过第一个字母( 到目前为止,我已经提出了这个:
for (i = 0; i < length - 1; i++) {
min_pos = i;
for (j = i + 1; j < length; j++) // find min
if (array[j].word[0] < array[min_pos].word[0]) {
min_pos = j;
}
swap = array[min_pos]; // swap
array[min_pos] = array[i];
array[i] = swap;
}
这段代码非常适合按字母顺序排序,但我无法编写正确的代码来按字母顺序和长度排序。
创建一个比较器函数。
将operator<
添加到您的List
:
bool operator<(const List &lhs) const {
if(word[0] != lhs.word[0]) {
return word[0] < lhs.word[0];
}
return strlen(word) < strlen(lhs.word);
}
现在使用此运算符进行排序,使用您喜欢的任何算法。
其他人指出,有更快、更干净的排序方法。但是,如果您想使用自己的选择排序,就像您编写的那样,那么您只需要对代码进行一些更改。
将"我需要交换"逻辑与交换逻辑本身分开。然后代码变得更加清晰,并且更清楚地在哪里添加额外的检查。
我在这里只复制了内部循环。您需要将现有的内部循环替换为此内部循环。我不清楚为什么你需要swap_pos
和min_pos
,所以我不理会语义。
for (j = i + 1; j < length; j++) { // find min
// first, determine whether you need to swap
// You want to swap if the first character of the new word is
// smaller, or if the letters are equal and the length is smaller.
bool doSwap = false;
if (array[j].word[0] < array[min_pos].word[0]) {
doSwap = true;
}
else if (array[j].word[0] == array[min_pos].word[0] &&
strlen(array[j].word) < array[min_pos].word) {
doSwap = true;
}
// do the swap if necessary
if (doSwap) {
swap_pos = j;
swap = array[min_pos]; // swap
array[min_pos] = array[i];
array[i] = swap;
}
}
为了更清楚地说明必要的逻辑更改,我有意避免进行重大的样式更改或简单的优化。
您可以将 lambda 传递给sort
来执行此操作:
sort(begin(array), end(array), [](const auto& lhs, const auto& rhs){ return *lhs.word < *rhs.word || *lhs.word == *rhs.word && (strlen(lhs.word) < strlen(rhs.word) || strlen(lhs.word) == strlen(rhs.word) && strcmp(lhs.word, rhs.word) < 0); });
现场示例
使用元组词典比较运算符
不编写此条件的一种简单方法是
#include <tuple>
然后可以使用std::tie
:
std::tie(array[j].word[0], array[j].repeat) < std::tie(array[min_pos].word[0], array[min_pos].repeat)
这是有效的std::tie
因为它创建了对其参数的左值引用元组。(这意味着std::tie
需要变量。如果您想比较函数的结果std::make_tuple
或std::forward_as_tuple
会更好(
std::tuple
有运算符
按字典顺序比较 lhs 和 rhs,即比较第一个元素(如果它们是等效的(,则比较第二个元素,如果它们是等效的,则比较第三个元素,依此类推。
而上面的描述也是如何对比价值不止于此的想法。
相关文章:
- 读取一组用户输入,按升序排序,然后打印结果
- C++ 按数值对元组<字符串、浮点数>然后按字典顺序排序的向量
- 修改的选择排序,选择最大的数字,然后交换到最后
- 如何创建一个C++程序来读取字符串数组中的信息,然后将其排序到类中?
- 如何根据长度然后字母顺序对数组字符串进行排序?
- 从文件中读取并将其内容放入对象数组中,然后对它们进行排序
- 对数组进行排序的算法,先是第一个元素,然后是前 2 个元素,然后是前 3 个元素,依此类推
- 按字母顺序排序字符数组,然后按长度排序
- 按第一个值的递减顺序对一组对进行排序,然后按第二个值的字母顺序排序
- 制作一个对的向量,对其进行排序,然后从中提取向量
- 根据标准对结构向量进行排序,然后显示结果
- 我有不同的类,我想用这些类中的对象制作一个向量,然后按值对其进行排序
- 读取中的链接列表,然后按名称进行排序
- 从文本文件将整数读入简单的链表中.然后对整数列表进行气泡排序并读出到另一个文件
- 是否有插入然后排序的替代方法
- c++我需要将文件中的数据读取到多维数组中,然后用一种数据类型对数组进行排序.怎样
- 插入最有效的数据结构,然后使用不同的条件进行排序
- 如何按第一个,然后是第二个,然后是第三个对 2d 数组进行排序,..使用 C++ 的列
- 对输入'age'名称进行排序,然后显示结果
- 提升ASIO-获得排序的端点(首先是IPv4,然后是IPv6)