简体   繁体   English

用冒泡排序算法排序字符串

[英]sorting strings with bubble sort algorithm

This code stores the number of words in an integer variable and the words in a multidimensionnel string then sorts the words alphabetically using a function. 此代码存储整数变量中的单词数,然后多维数字符串中的单词使用函数按字母顺序对单词进行排序。 The problem I have is in the function call. 我遇到的问题是在函数调用中。

#include<stdio.h>
#include<string.h>
void sort(char*[50],int);
int main ()
{
    int i,n=0;
    char s[50][10];

    scanf("%d",&n);//scaning the number of words

    for(i=0;i<=n;i++)//scaning the words
    gets(s[i]);

    sort(s,n);

    for(i=0;i<=n;i++)//printing the words sorted
    printf("%s\n",s[i]);
}
void sort(char*s[50],int n)
{
    int i,j,cmp;
    char tmp[1][10];

    //bubble sorting of words
    for(i=0; i<n; i++)
        for(j=0; j<n-1; j++)
        {
            cmp=strcmp(s[j],s[j+1]);

            if(cmp>0)
            {
                strcpy(tmp[0],s[j+1]);
                strcpy(s[j+1],s[j]);
                strcpy(s[j],tmp[0]);
            }   
        }
}

Turn on your warnings. 打开你的警告。 char s[50][50] is not convertible to char* . char s[50][50]不能转换为char*

Try this: 尝试这个:

void sort(char(*)[50],int);

This tells the compiler you pass in a pointer to at least one buffer of 50 characters. 这告诉编译器传入指向至少一个50个字符的缓冲区的指针。 This is what multidimensional arrays decay to when passed into functions. 这是多维数组在传递给函数时衰减的内容。

And to further rid you of the silly notion that " char[] is the same as char* ", which for some reason is still taught everywhere, read this: http://c-faq.com/aryptr/aryptr2.html 并且为了进一步摆脱“ char[]char*相同的愚蠢概念”,由于某种原因仍然在各地教授,请阅读: http//c-faq.com/aryptr/aryptr2.html

You're close. 你很亲密 Here's a working version of your code. 这是您的代码的工作版本。 Note that the scanf() leaves the newline from the number for the ... fgets() , because you won't ever use gets() again, will you? 请注意, scanf()从... fgets()的数字中留下换行符,因为你不会再使用gets() ,是吗? ... so you need to read up to and including the newline after the scanf() . ...所以你需要在scanf()之后阅读并包括换行符。 Of course, there's the interesting question of 'why do people think it is better for humans to count than to make computers count instead?' 当然,有一个有趣的问题是“为什么人们认为人类计算比计算机数更好呢?” It would be more sensible not to bother with the count. 如果不打扰计数会更明智。 Note that the revised code validates n to ensure it is not larger than 50. 请注意,修订后的代码验证n以确保它不大于50。

Revised code that works on lines of length 9 or shorter 修改后的代码适用于长度为9或更短的行

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

void sort(char s[50][10], int);

int main(void)
{
    int i;
    int n = 0;
    char s[50][10];
    char line[11];

    if (scanf("%d", &n) != 1)
    {
        fprintf(stderr, "Failed to read a number\n");
        return 1;
    }
    if (n <= 0 || n > 50)
    {
        fprintf(stderr, "%d is out of the range 1..50\n", n);
        return 1;
    }
    // Gobble rest of first line
    while ((i = getchar()) != EOF && i != '\n')
        ;

    for (i = 0; i < n; i++)
    {
        if (fgets(line, sizeof(line), stdin) == 0)
            break;
        // Remove newline from input
        size_t len = strlen(line);
        assert(len > 0 && len <= sizeof(s[i]));
        line[len-1] = '\0';
        strcpy(s[i], line);
    }
    n = i;  // In case the file was shorter than stated!

    printf("Before:\n");
    for (i = 0; i < n; i++)
        printf("%s\n", s[i]);

    sort(s, n);

    printf("After:\n");
    for (i = 0; i < n; i++)
        printf("%s\n", s[i]);

    return 0;
}

void sort(char s[50][10], int n)
{
    int i, j, cmp;
    char tmp[10];

    if (n <= 1)
        return; // Already sorted

    for (i = 0; i < n; i++)
    {
        for (j = 0; j < n-1; j++)
        {
            cmp = strcmp(s[j], s[j+1]);

            if (cmp > 0)
            {
                strcpy(tmp, s[j+1]);
                strcpy(s[j+1], s[j]);
                strcpy(s[j], tmp);
            }
        }
    }
}

This code reads lines into a string long enough to take up to 9 data characters, a newline, and the terminal null. 此代码将行读入字符串足够长的时间,最多可占用9个数据字符,换行符和终止值为null。 It removes the newline, leaving up to 9 data characters and a terminal null. 它删除换行符,最多留下9个数据字符,终止为null。

Sample run: 样品运行:

Before:
Number 34
Number 39
Number 32
Number 30
Number 22
Number 34
Number 57
Number 28
Number 30
Number 47
Number 43
Number 23
Number 22
After:
Number 22
Number 22
Number 23
Number 28
Number 30
Number 30
Number 32
Number 34
Number 34
Number 39
Number 43
Number 47
Number 57

Original code that works on lines of length 8 or shorter 适用于长度为8或更短的行的原始代码

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

void sort(char s[50][10], int);

int main(void)
{
    int i;
    int n = 0;
    char s[50][10];

    if (scanf("%d", &n) != 1)
    {
        fprintf(stderr, "Failed to read a number\n");
        return 1;
    }
    if (n <= 0 || n > 50)
    {
        fprintf(stderr, "%d is out of the range 1..50\n", n);
        return 1;
    }
    // Gobble rest of first line
    while ((i = getchar()) != EOF && i != '\n')
        ;

    for (i = 0; i < n; i++)
    {
        if (fgets(s[i], sizeof(s[i]), stdin) == 0)
            break;
        // Remove newline from input
        size_t len = strlen(s[i]);
        assert(len > 0);
        s[i][len-1] = '\0';
    }
    n = i;  // In case the file was shorter than stated!

    printf("Before:\n");
    for (i = 0; i < n; i++)
        printf("%s\n", s[i]);

    sort(s, n);

    printf("After:\n");
    for (i = 0; i < n; i++)
        printf("%s\n", s[i]);

    return 0;
}

void sort(char s[50][10], int n)
{
    int i, j, cmp;
    char tmp[10];

    if (n <= 1)
        return; // Already sorted

    for (i = 0; i < n; i++)
    {
        for (j = 0; j < n-1; j++)
        {
            cmp = strcmp(s[j], s[j+1]);

            if (cmp > 0)
            {
                strcpy(tmp, s[j+1]);
                strcpy(s[j+1], s[j]);
                strcpy(s[j], tmp);
            }
        }
    }
}

The 'big' change is the way the function array parameter is declared and defined. “大”变化是声明和定义函数数组参数的方式。 You're passing an array of 50 rows with 10 characters per row, so simply specify that in the function. 您传递的是50行的数组,每行10个字符,因此只需在函数中指定。 You could drop the 50 from the dimensions of the function parameter with no change to the program's behaviour. 您可以从函数参数的维度中删除50,而不会更改程序的行为。

Sample input: 样本输入:

8
fed
abc
cba
def
hij
cba
xyz
aaa

Example run: 示例运行:

$ ./srt < data
Before:
fed
abc
cba
def
hij
cba
xyz
aaa
After:
aaa
abc
cba
cba
def
fed
hij
xyz
$

The fact that this needed revising shows the importance of testing the limits (and carefully defining the limits). 需要修改的事实表明了测试极限的重要性(并仔细定义了极限)。

The code as revised is still not general purpose code. 修订后的代码仍然不是通用代码。 The fixed limit of at most 50 lines of input, the count of the number of lines required as part of the input, and the fixed line length of at most 10 characters per line all make it toy code. 最多50行输入的固定限制,作为输入一部分所需的行数,以及每行最多10个字符的固定行长度都使其成为玩具代码。 As such, GIGO (garbage in, garbage out) is not an unreasonable reaction. 因此,GIGO(垃圾进,垃圾出)不是不合理的反应。 If the data file contains overlong lines, you get what you get. 如果数据文件包含超长行,则可以获得所获得的内容。 The code won't crash, but the output may not make much sense. 代码不会崩溃,但输出可能没有多大意义。

change 更改

void sort(char*[50],int);
...
void sort(char*s[50],int n)

to

void sort(char(*)[10],int);//not char(*)[50]
...
void sort(char(*s)[10],int n)

and

//remain newline
scanf("%d",&n);

to

scanf("%d%*c",&n);//read and drop newline

so change 所以改变

for(i=0;i<=n;i++)

to

for(i=0;i<n;i++)

or 要么

char *p[50];
for(i=0;i<n;++i)
    p[i]=&s[i][0];
sort(p,n);//OK only exchange of pointer in this case

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM