C语言 如何将字符气泡排序转换为按字符串长度排序的字符串气泡排序

gtlvzcf8  于 2023-01-20  发布在  其他
关注(0)|答案(2)|浏览(135)

我已经写了一个基本的冒泡排序程序,它使用从一个预定数组或字符中给定的输入,但我想改变它,这样我就可以对字符串排序,而且我不想按字母顺序排序,而是按字符串长度排序。
我的来源. c

void sort(char array[], int size) {
    for (int i = 0; i < size - 1; i++) {
        for (int j = 0; j < size - i - 1; j++) {
            if (array[j] > array[j + 1]) {
                int temp = array[j];
                array[j] = array[j + 1];
                array[j + 1] = temp;
            }
        }
    }
}

void printArray(char array[], int size) {
    for (int i = 0; i < size; i++) {
        printf("%c ", array[i]); //%c -> %s
    }
}

int main(void) {

    char array[] = { 'F', 'A', 'D', 'B', 'C' };
        //char string[][] = { "hey", "Hello", "awesome" };

    int size = sizeof(array) / sizeof(array[0]);

    sort(array, size);
    printArray(array, size);

    return 0;
}

我曾尝试将int main(void)中的char array[];作为char string[][];的字符串数组,并尝试进行相应的更改,但一直失败(构建错误)。我也不明白应该如何将其更改为按字符串长度排序,而不是按字母顺序排序

ev7lccsx

ev7lccsx1#

对于初学者来说,要注意你的函数实现是低效的,因为它的嵌套循环会对一个已经排序的数组执行很多次,也就是说,这个函数没有考虑到数组的一部分(或者整个数组)已经排序。
如果你想根据某个条件对数组排序,那么你应该在声明函数时多加一个参数,这个参数将指定一个比较函数,类似于标准的C函数qsort
所以提供不同的函数,你可以用不同的元素比较规则对同一个数组排序。
你总是应该写一些更通用的函数。
下面是一个演示程序,展示如何为二维字符数组编写实现冒泡排序方法的函数。

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

enum { N = 6 };

void bubble_sort( char s[][N], size_t n, int cmp( const void *, const void * ) )
{
    for (size_t sorted = 1; !( n < 2 ); n = sorted)
    {
        for (size_t j = sorted = 1; j < n; j++)
        {
            if (cmp( &s[j], &s[j - 1] ) < 0)
            {
                char tmp[N];
                strcpy( tmp, s[j] );
                strcpy( s[j], s[j - 1] );
                strcpy( s[j - 1], tmp );

                sorted = j;
            }
        }
    }
}

static int by_length( const void *a, const void *b )
{
    char ( *s1 )[N] = ( char( * )[N] )a;
    char( *s2 )[N] = ( char( * )[N] )b;

    size_t n1 = strlen( *s1 );
    size_t n2 = strlen( *s2 );

    return ( n2 < n1 ) - ( n1 < n2 );
}

static int lexicographically( const void *a, const void *b )
{
    char( *s1 )[N] = ( char( * )[N] )a;
    char( *s2 )[N] = ( char( * )[N] )b;

    return strcmp( *s1, *s2 );
}

int main( void )
{

    char s[][N] =
    {
        "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten"
    };

    const size_t M = sizeof( s ) / sizeof( *s );

    for (size_t i = 0; i < M; i++)
    {
        printf( "\"%s\" ", s[i] );
    }

    putchar( '\n' );

    bubble_sort( s, M, by_length );

    for (size_t i = 0; i < M; i++)
    {
        printf( "\"%s\" ", s[i] );
    }

    putchar( '\n' );

    bubble_sort( s, M, lexicographically );

    for (size_t i = 0; i < M; i++)
    {
        printf( "\"%s\" ", s[i] );
    }

    putchar( '\n' );
}

程序输出为

"One" "Two" "Three" "Four" "Five" "Six" "Seven" "Eight" "Nine" "Ten"
"One" "Two" "Six" "Ten" "Four" "Five" "Nine" "Three" "Seven" "Eight"
"Eight" "Five" "Four" "Nine" "One" "Seven" "Six" "Ten" "Three" "Two"

如果编译器支持变长数组,则可以编写更通用的函数。
例如,在这种情况下,函数声明可以类似于

void bubble_sort( size_t m, size_t n, char s[m][n], int cmp( const void *, const void * ) )
9udxz4iz

9udxz4iz2#

你需要修改sort()printArray()来获取一个字符串数组,然后修改compare函数来使用strlen()来查找相同的字符串,你可以对数组进行预处理,一次而不是n^2次地获取所有的大小,这对于小的输入没有关系,我按照大小(<)对它进行了反向排序,因为输入数组已经按照大小递增进行了排序:

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

void sort(size_t size, char *array[size]) {
    for (int i = 0; i < size - 1; i++) {
        for (int j = 0; j < size - i - 1; j++) {
            if (strlen(array[j]) < strlen(array[j + 1])) {
                char *temp = array[j];
                array[j] = array[j + 1];
                array[j + 1] = temp;
            }
        }
    }
}

void printArray(size_t size, char *array[size]) {
    for (int i = 0; i < size; i++) {
        printf("%s ", array[i]); //%c -> %s
    }
}

int main(void) {
    char *array[] = { "hey", "Hello", "awesome" };
    size_t size = sizeof array / *sizeof array[0];
    sort(size, array);
    printArray(size, array);
}

运行示例:

awesome Hello hey

相关问题