【问题标题】:Sort a 2D array of strings in C在C中对二维字符串数组进行排序
【发布时间】:2014-08-10 05:33:09
【问题描述】:

我目前正在从文件中读取单词列表并尝试逐行对它们进行排序。 我可以读入每一行并将单词打印出来,但我似乎无法单独对每一行进行排序。第一行已排序,但第二行未排序。谁能看到我哪里出错了?谢谢!

    int fd;
    int n_char = 0;
    int charCount = 0, wordCount = 0, lineCount = 0;
    int wordsPerLine[100];

    char buffer;
    char words[6][9];

    fd = open(inputfile, O_RDONLY);
    if (fd == -1) {
        exit(1);
    }

    wordsPerLine[0] = 0;

    /* use the read system call to obtain 10 characters from fd */
    while( (n_char = read(fd, &buffer, sizeof(char))) != 0) {

        if (buffer == '\n' || buffer == ' ') {
            words[wordCount][charCount] = '\0';
            charCount = 0;
            wordCount++;
            wordsPerLine[lineCount] += 1;
            if (buffer == '\n') {
                lineCount++;
                wordsPerLine[lineCount] = 0;
            }
        } else {
            words[wordCount][charCount++] = buffer;
        }
    }

    printf("Num Words: %d  ---  Num Lines: %d\n", wordCount, lineCount);

    char tmp[9];

    int m, n;
    int i, x, totalCount = 0;
    for (i = 0; i < lineCount; i++) {
        for (x = 0; x < wordsPerLine[i]; x++) {

            /* iterate through each word 'm' in line 'i' */
            for(m = 0; m < wordsPerLine[i]; m++) {
                for(n = 0; n < wordsPerLine[i]; n++) {
                    if(strcmp(words[n-1], words[n])>0) {
                        strcpy(tmp, words[n-1]);
                        strcpy(words[n-1], words[n]);
                        strcpy(words[n], tmp);
                    }
                }
            } /* end sorting */

        }
    }

    printf("Sorted:\n");
    totalCount = 0;
    for(i = 0; i < lineCount; i++) {
        printf("Line %d (%d words)\n", i + 1, wordsPerLine[i]);
        for(x = 0; x < wordsPerLine[i]; x++) {
            printf("%s\n", words[totalCount++]);
        }
    }

我的示例输入文件是:

great day out
foo bar food

【问题讨论】:

  • 你的期望输出是? “美好的一天”和“酒吧美食”?
  • 你目前得到了什么?
  • 如果输入的最后一行不以换行符结尾,则问题可能是您不会终止数据。 OTOH,输入文件不太可能不以换行符结尾。
  • 你必须用前面所有行的wordsPerLine 的总和来索引nth 行的单词。我猜你对第一行进行了两次排序,因为你总是从 0 开始计算单词,而你应该从第二行的 3 开始计算。 (在打印单词时使用totalCount 来说明这一点,但在对它们进行排序时不会。)
  • 另外,当n 从 0 开始时,您不应该访问words[n - 1]。使用1 开始内部循环,或者使用m + 1 更好。

标签: c arrays sorting multidimensional-array


【解决方案1】:

让我们从小部分开始......

看问题是否出在阅读中,评论阅读部分并尝试补充:

 char words[][9] = {"great", "day", "out", "foo", "bar", "food"};

并将计数器设置为使用此输入时的值...

您的循环正在访问一些超出范围的数据...我建议您先尝试使用数字数组对您的排序代码进行排序,看看它是否对它们进行了正确排序...

#include<stdio.h>
#define N 6
int main()
{
   char words[][9] = {"great", "day", "out", "foo", "bar", "food"};
   int numbers[] = {20, 10, 50, 5, 30, -50};
   int i, j, temp;

   for(i = 0; i < N - 1; i++)
      for(j = 0; j < N - 1; j++)
          if(numbers[j] > numbers[j + 1])
          {
             temp = numbers[j];
             numbers[j] = numbers[j + 1];
             numbers[j + 1] = temp;
          }


    for(i = 0; i < N; i++)
    {
        printf("%d\n", numbers[i]);
        //printf("%s\n", words[i]);
    }
}

还要注意,这是冒泡排序效率最低的实现(但与您提供的相同),您可以通过添加一个变量来检查内部循环中发生的一些变化(这意味着它是已经排序,你可以停止排序)...

此外,在外循环的每次迭代之后,一个元素将被放置在其最终位置(尝试找出哪个元素),这意味着您不需要在下一次迭代中考虑这个元素,所以在外循环中的每次迭代之后,在内循环中比较的元素数量可以减少 1...

你可以找到更多关于冒泡排序的信息here

【讨论】:

  • 我终于想通了!不过感谢您的帮助!
【解决方案2】:
/* iterate through each line */
for (i = 0; i < lineCount; i++) { 

    /* iterate through each word 'm' in line 'i' */
    for(m = 0; m < wordsPerLine[i]; m++) {
        for(n = m+1; n < wordsPerLine[i]; n++) {
            if(strcmp(words[n + totalCount], words[m + totalCount]) < 0) {
                strcpy(tmp, words[m + totalCount]);
                strcpy(words[m + totalCount], words[n + totalCount]);
                strcpy(words[n + totalCount], tmp);
            }
        }
    } /* end sorting */  
    totalCount += wordsPerLine[i];
}

我只需要保持每行每个单词的运行计数,所以我知道从哪一行开始比较

【讨论】:

    猜你喜欢
    • 2021-08-16
    • 2011-02-17
    • 1970-01-01
    • 2011-07-01
    • 2013-05-26
    • 2021-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多