字符串插入排序程序

时间:2015-11-15 20:33:25

标签: c arrays string sorting

我刚刚开始倾向于C,所以我不太了解它。我们给出的程序告诉我们编写一个插入排序程序,它按空格分隔20个字符串,然后按字母顺序排序并按顺序打印出来。这让我很困惑,因为C没有String数据类型(至少据我所知)。字符串不是字符串吗?这是我得到的:

#include <stdio.h>
#include <string.h>
#define MAX_STRINGS 20

void InsertionSort(char list[]);

void main()
{
    int index;
    char strings[MAX_STRINGS];

    /* Get input */
    printf("Enter %s strings.\n", MAX_STRINGS);
    for (index = 0; index < MAX_STRINGS; index++)
    {
        char tempString[100];
        printf("Input string %d : ", index);
        scanf("%s", &tempString[0]);
        strings[index] = tempString;
    }

    InsertionSort(strings);

    printf("\nThe input set, in alphabetical order:\n");
    for (index = 0; index < MAX_STRINGS; index++)
    {
        printf("%s\n", strings[index]);
    }
}

void InsertionSort(char list[])
{
    int unsorted;
    int sorted;
    char unsortedItem;

    for(unsorted = 1; unsorted < MAX_STRINGS; unsorted++)
    {
        unsortedItem = list[unsorted];

        for (sorted = unsorted - 1; (sorted >= 0) && (list[sorted] >  unsortedItem); sorted--)
        {
            list[sorted + 1] = list[sorted];
        }
        list[sorted + 1] = unsortedItem;
    }
}

我对C和C语法完全陌生,我发现它很混乱。此程序无法正常工作。它正在做的是它允许我输入20个字符串,但是没有任何东西被排序并且它什么也没有打印出来。关于如何解决这个问题的任何想法?另外,有什么想法我怎么能把它输入到我输入单个句子的地方,每个字符串用空格分隔?例如,如果我打字,“我正在学习如何用C编程,现在我不喜欢它。”这会给我16个字符串。 “我”,“我”,“学习”等等。谢谢。

2 个答案:

答案 0 :(得分:3)

原始代码存在一些问题:

1)您无法使用=复制字符串;使用strncpy即可(使用=仅指定指针)。

2)字符串是一个字符数组;因此,字符串数组是字符数组的数组(因此您的InsertionSort签名是错误的)。请注意,C字符串是空终止的,这意味着值为0的字节表示字符串的结尾(这非常重要,如果您忘记其他所有内容,请记住这一点)。

3)%s期待char*;这一行产生UB:printf("Enter %s strings.\n", MAX_STRINGS);。您想要的是%d(请阅读printf格式说明符)。

4)你不能使用普通算术运算符来比较字符串;那些比较指针。您需要使用strcmp

5)插入排序算法的实现是错误的。

6)标准允许的main声明版本有几个版本,char main不是其中之一。在这种情况下,只需使用int main

以下是您的代码的固定版本:

#include <stdio.h>
#include <string.h>
#define MAX_STRINGS 20
#define MAX_STRING_LEN 200

void InsertionSort(char list[MAX_STRINGS][MAX_STRING_LEN]);

int main()
{
    int index;
    char strings[MAX_STRINGS][MAX_STRING_LEN];

    /* Get input */
    printf("Enter %d strings.\n", MAX_STRINGS);
    for (index = 0; index < MAX_STRINGS; index++)
    {
        printf("Input string %d : ", index);
        scanf("%199s", strings[index]);     // limit the width so we don't go past the buffer
        strings[index][sizeof(strings[index]) - 1] = '\0';
    }

    InsertionSort(strings);

    printf("\nThe input set, in alphabetical order:\n");
    for (index = 0; index < MAX_STRINGS; index++)
    {
        printf("%s\n", strings[index]);
    }
}

void InsertionSort(char list[MAX_STRINGS][MAX_STRING_LEN])
{
    for (int i = 1; i < MAX_STRINGS; i++)
    {
        int j = i;

        while (j > 0 && strcmp(list[j - 1], list[j]) > 0)
        {
            char tmp[MAX_STRING_LEN];
            strncpy(tmp, list[j - 1], sizeof(tmp) - 1);
            tmp[sizeof(tmp) - 1] = '\0';

            strncpy(list[j - 1], list[j], sizeof(list[j - 1]) - 1);
            list[j - 1][sizeof(list[j - 1]) - 1] = '\0';

            strncpy(list[j], tmp, sizeof(list[j]));
            list[j][sizeof(list[j]) - 1] = '\0';

            --j;
        }
    }
}

起初这可能有点压倒性,但要慢慢仔细阅读,你应该没有问题。

= '\0'strncpy之后的scanf - 这些函数不会隐式地终止字符串,因此我们必须手动执行此操作 - 您可能会在不执行此操作的情况下离开几次,但从长远来看,它最终会回到你身边。保持安全,养成习惯。

其他人:如果你发现任何错误,请告诉我 - 已经很晚了,我已经累了。

关于您在评论中提出的问题:

1)为什么我从for循环中的1开始? 因为我稍后提到list[j - 1],并且j设置为i(最初)的值,所以它不能小于1或我们是使用负指数。有关算法的说明,请参阅here

2)如何读取整行的字符串,包括空格?
最好的解决方案是使用fgets。请注意,它有一个怪癖:它还将\n字符存储在数组中。如果您不想要它,则必须手动将其删除。

3)什么是tmp? 这只是一个临时的char缓冲区,所以我可以根据算法的要求交换这两个字符串。这不是特定于字符串,通常交换两个变量,你需要第三个,临时的(除非你选择一些脏的XOR黑客)。

答案 1 :(得分:1)

使用此功能按字母顺序对字符串进行排序:

int s_bubblesortA(int argc,char **argv)
{
    int i , j = 0;
    char *p_1 , *p_2 , *tmp;
    while( j < argc )
    {
        for( i = 0 ; i < argc - j - 1 ; i++ )
        {
            p_1 = argv[i] , p_2 = argv[i+1];
            while( *p_1 && *p_2 )
            {
                if( *p_1 < *p_2 )
                    break;
                else if( *p_1 > *p_2 || ( ! *(p_2 + 1) && ( *p_1 == *p_2 ) && *(p_1+1) ) )
                {
                    tmp = argv[i];
                    argv[i] = argv[i+1];
                    argv[i+1] = tmp;
                    break;
                }
                p_1++;
                p_2++;
            }
        }
        j++;
    }
    return 0;
}

注意:请查看此链接,以便我对类似帖子的完整答案。sort words alphabeticaly in C