假设我有两个数组,其中一个包含某些数字,另一个包含与这些数字对应的名称,以 sums[i]
与 names 关联的方式[i]
.
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
int main()
{
char *names[] = {"William","Olivia","Willaim","Olivai","Lily","Lyli"};
int sums[6] = {58, 48, 58, 48, 30, 30};
int i, j, s = 6;
char *temp_char;
int temp_int;
for(i=0 ; i < s-1 ; i++){
for (j=0; j<s-i; j++){
if (sums[j]<sums[j+1]){
temp_char = names[j+1];
temp_int = sums[j+1];
names[j+1] = names[j];
sums[j+1] = sums[j];
names[j] = temp_char;
sums[j] = temp_int;
}
if ((sums[j] == sums[j+1]) && (strcmp(names[j], names[j+i])>0)) {
temp_char = names[j+1];
names[j+1] = names[j];
names[j] = temp_char;
}
}
}
for (i = 0; i<s; i++){
printf("%d ", sums[i]);
printf("%s\n", names[i]);
}
return 0;
}
这是原始代码的一部分,已编译但未真正正确排序。然而,这个突然返回段错误。
为什么我突然收到这个错误,为什么排序不起作用?
最佳答案
您的程序没有执行到段错误。 (至少在 Ubuntu 中通过 GCC 7.2 编译和执行时)。 但是,您可能需要关注一些要点,以便让您的排序部分顺利进行。
- 关注这一行:
for (j=0; j<s-i; j++)
. 在这里,j
的最终值将获得 5. 怎么样?您已声明s
在初始化期间为 6,最小值为i
为 0。所以默认情况下j
可以在 0 到 5 之间(注意j
必须小于s-i
,因此for
循环不会让它超过 5)。但它如何影响你的逻辑?现在如果j
的最大值获取的是 5,则j+1
的最大值将是 6。因此,当您在最末端(在 j=5 处)执行交换时,您可能会在数组中得到一个垃圾值。只要多次执行代码,您就会注意到这一事实。要解决此问题,只需使用for (j=0; j<s-i-1; j++)
. - 现在来到包含这个
(strcmp(names[j], names[j+i])>0)
的行陈述。 您的代码表示您正在以降序方式使用冒泡排序。因此,要在这里发生这种情况,您需要有(strcmp(names[j+1], names[j])>0)
.这将允许您将第 (j+1) 个索引处的字符串与第 j 个索引处的字符串进行比较。如果第 (j+1) 个索引处的字符串大于第 j 个索引处的字符串,那么您可以进行交换(因为您希望以降序方式进行排序)。
为了将上述想法付诸实践,我们开始吧:
#include <stdio.h>
#include <string.h>
int main()
{
char *names[] = {"William","Olivia","Willaim","Olivai","Lily","Lyli"};
int sums[6] = {58, 48, 58, 48, 30, 30};
int i, j, s = 6;
char *temp_char;
int temp_int;
for(i=0 ; i < s ; i++){
for (j=0; j<s-i-1; j++){ //Change 1
if (sums[j]<sums[j+1]){
temp_char = names[j+1];
temp_int = sums[j+1];
names[j+1] = names[j];
sums[j+1] = sums[j];
names[j] = temp_char;
sums[j] = temp_int;
}
if ((sums[j] == sums[j+1]) && (strcmp(names[j+1], names[j])>0)) { //Change 2
temp_char = names[j+1];
names[j+1] = names[j];
names[j] = temp_char;
}
}
}
for (i = 0; i<s; i++){
printf("%d ", sums[i]);
printf("%s\n", names[i]);
}
return 0;
}
对您的代码的建议:使用 struct
结合你的names
和 sums
排列在一起。效率方面它看起来并不多,但它会帮助您的代码看起来更简洁。
关于c - 无法正确排序字符串数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57350955/