【问题标题】:Sorting an array of strings in an alphabetical order using pointers使用指针按字母顺序对字符串数组进行排序
【发布时间】:2020-03-14 02:10:00
【问题描述】:

我有一个项目,我必须创建一个程序,让用户以任何顺序输入姓名。然后程序按字母顺序显示名称。此外,所有这些都必须使用指针来完成。现在我对程序的尝试提示用户输入名称并显示它们,但由于某种原因我无法对其进行排序。有人可以帮我吗?

这是我对该程序的尝试:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main() {
  int list;
  char *names[20];
  char str[20];
  printf("Enter the number of names: ");
  scanf("%d", &list);
  fflush(stdin);
  for (int i = 0; i < list; i++) {
    printf("Enter name %d: ", i + 1);
    // gets(str);
    scanf("%[^\t\n]s", str);
    fflush(stdin);
    names[i] = (char *)malloc(strlen(str) + 1);
    strcpy(names[i], str);
  }
  void sortNames();
  for (int i = 0; i < 5; i++)
    printf("%s\n", names[i]);
  return 0;
}

void sortNames(char **name, int *n) {
  int i, j;
  for (j = 0; j < *n - 1; j++) {
    for (i = 0; i < *n - 1; i++) {
      if (compareStr(name[i], name[i + 1]) > 0) {
        char *t = name[i];
        name[i] = name[i + 1];
        name[i + 1] = t;
      }
    }
  }
}

int compareStr(char *str1, char *str2) {
  while (*str1 == *str2) {
    if (*str1 == '\0' || *str2 == '\0')
      break;

    str1++;
    str2++;
  }
  if (*str1 == '\0' && *str2 == '\0')
    return 0;
  else
    return -1;
}

【问题讨论】:

  • 我假设您出于教学原因正在编写自己的compareStr 函数,但如果您不是,您可能希望使用strcmp(来自string.h)来代替。
  • 你不能用qsort吗?还是需要您编写自己的排序函数?
  • @kopecs 是的,我正在编写自己的 compareStr,这是一个要求。
  • @TomKarzes 我得自己写排序函数
  • 我不清楚您为什么将n 作为sortNames 中的指针。还值得注意的是,您的 compareStr 函数永远不会返回 1。str1 更大的预期处理是什么?

标签: c sorting pointers string-comparison


【解决方案1】:

只关注排序问题,主要的一个是你永远不会调用你以后定义的排序函数。线

void sortNames();

仅用于声明一个标识符为 sortNames 的函数,该函数接受任意数量的任意类型的参数(可能不是您想要做的)。我建议将此行修改为

sortNames(names, list); // Not &list because I'm about to suggest not taking it as a pointer

然后对于sortNames 函数本身,我并不完全清楚为什么您将要排序的数组长度作为指针而不是仅传递int 本身。我建议将这个函数修改为

void sortNames(char **name, int n) {
  int i, j;
  for (j = 0; j < n - 1; j++) {
    for (i = 0; i < n - 1; i++) {
      if (compareStr(name[i], name[i + 1]) > 0) {
        char *t = name[i];
        name[i] = name[i + 1];
        name[i + 1] = t;
      }
    }
  }
}

目前的一个问题是表达式compareStr(name[i], name[i + 1]) &gt; 0 总是错误的。这是因为 compareStr 只返回 0 或 -1。您可以通过重写compareStr 来解决此问题,以正确处理*str1 &gt; *str2 的情况。一种可能的方法是

int compareStr(char *str1, char *str2) {
    if (*str1 == '\0' && *str2 == '\0') {
        return 0;
    } else if (*str1 > *str2) {
        return 1;
    } else if (*str1 < *str2) {
        return -1;
    }
    return compareStr(str1 + 1, str2 + 1);
}

虽然如果你写这篇文章是为了学习,我建议你尝试修改你当前的迭代解决方案,而不是仅仅复制和粘贴这个版本。

最后,因为您想在定义它们之前使用这些函数,您应该在使用它们之前移动它们的定义(即,有compareStr,然后是sortNames,然后是main)或在文件开头为这些函数提供前向声明,即添加

void sortNames(char **name, int n);
int compareStr(char *str1, char *str2);

在您的main上方。


正如其他人所指出的那样,您可能希望避免 fflush(stdin) 作为其未定义的行为,我建议不要使用 casting the result of malloc

【讨论】:

    【解决方案2】:

    这里的问题是函数compareStr永远不会返回大于0的值。它只是告诉你两个字符串是否相似。

    为了排序,需要额外添加如下逻辑:

    int compareStr(char *str1, char *str2) {
        while (*str1 == *str2) {
    
            if (*str1 == '\0' || *str2 == '\0')
                break;
    
            str1++;
            str2++;
        }
        if (*str1 == '\0' && *str2 == '\0'){
            return 0;
        }
        else if(*str1 > *str2){
            return 1;
        }else{
            return -1;
        }
    }
    

    除此之外,您必须以 sortNames(names, &list) 的形式调用函数 sortNames,并确保函数定义以正确的顺序编写或使用函数声明。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-03
      • 1970-01-01
      • 2018-04-21
      • 2021-12-19
      相关资源
      最近更新 更多