C Primer Plus(6) 中文版 第11章 字符串和字符串函数 11.6 字符串示例:字符串排序

11.6 字符串示例:字符串排序
处理一个按字母表顺序字符串的实际问题。该程序主要是用strcmp()函数来确定两个字符串的顺序。一般的做法是读取字符串函数、排序字符串并打印出来。
/* sort_str.c -- reads in strings and sorts them */
#include <stdio.h>
#include <string.h>
#define SIZE 81        /* string length limit, including \0  */
#define LIM 20         /* maximum number of lines to be read */
#define HALT ""        /* null string to stop input          */
void stsrt(char *strings[], int num);/* string-sort function */
char * s_gets(char * st, int n);

int main(void)
{
    char input[LIM][SIZE];     /* array to store input       */
    char *ptstr[LIM];          /* array of pointer variables */
    int ct = 0;                /* input count                */
    int k;                     /* output count               */
    
    printf("Input up to %d lines, and I will sort them.\n",LIM);
    printf("To stop, press the Enter key at a line's start.\n");
    while (ct < LIM && s_gets(input[ct], SIZE) != NULL
           && input[ct][0] != '\0')
    {
        ptstr[ct] = input[ct];  /* set ptrs to strings        */
        ct++;
    }
    stsrt(ptstr, ct);          /* string sorter              */
    puts("\nHere's the sorted list:\n");
    for (k = 0; k < ct; k++)
        puts(ptstr[k]) ;       /* sorted pointers            */
    
    return 0;
}

/* string-pointer-sorting function */
void stsrt(char *strings[], int num)
{
    char *temp;
    int top, seek;
    
    for (top = 0; top < num-1; top++)
        for (seek = top + 1; seek < num; seek++)
            if (strcmp(strings[top],strings[seek]) > 0)
            {
                temp = strings[top];
                strings[top] = strings[seek];
                strings[seek] = temp;
            }
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    int i = 0;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        while (st[i] != '\n' && st[i] != '\0')
            i++;
        if (st[i] == '\n')
            st[i] = '\0';
        else // must have words[i] == '\0'
            while (getchar() != '\n')
                continue;
    }
    return ret_val;
}
/* 输出:

*/ 11.6.1 排序指针而非字符串
该程序的巧妙之处在于排序的是指向字符串的指针,而不是字符串本身。排序果果把ptrst重新排列,并未改变input。这样做比用strcpy交换两个input字符串的内容简单得多,而且还保留了input数组中的原始顺序。
11.6.2 选择算法排序
我们采用选择排序算法(selection sort algorithm)来排序指针。具体做法是,利用for循环依次把每个元素与首元素比较。如果待比较的元素在当前首元素的前面,则交换两者。循环结束时,首元素包含的指针指向机器排序序列最靠前的字符串。然后外层的for循环重复这一过程,这次从input的第2个元素开始。当内层循环执行完毕时,ptrst中的第2个元素指向排在第2的字符串。这一过程持续到所有元素都已排序完毕。
进一步分析选择排序的过程。下面是排序过程的伪代码:
for n = 首元素至 n = 倒数第2个元素,
    找出剩余元素中的最大值,并将其放在第n个元素中
具体过程如下。首先,从n = 0开始,遍历整个数组找出最大值元素,那该元素与第1个元素交换;然后设置n = 1,遍历除第1个元素以外的其他元素,在其余元素中找出最大值元素,然后设置n = 1,遍历除第1个元素以外的其他元素,在其余元素中找出最大值元素,把该元素与第2个元素交换;重复这一过程直至倒数第2个元素为止。现在只剩下两个元素。比较这两个元素,把较大者放在倒数第2的位置。这样,数组中的最小元素就在最后的位置上。
这看起来用for循环就能完成任务,但是我们还要更详细地分析“查找和放置”的过程。在剩余项中查找最大值的方法是,比较数组剩余元素的第1个元素和第2个元素。如果第2个元素比第1个元素大,交换两者。现在比较数组剩余元素的第1个元素和第3个元素,如果第3个元素比较大,交换两者。每次交换都把较大的元素移至顶部。继续这一过程直到比较第1个元素和最后一个元素。比较完毕后,最大值元素现在是剩余数组的首元素。已经排出了该数组的首元素,但是其他元素还是一团糟。下面是排序过程的伪代码:
for n - 第2个元素至最后一个元素,
    比较第n个元素与第1个元素,如果第n个元素更大,交换这两个元素的值。
看上去用一个for循环也能搞定。只不过要把它嵌套在刚才的for循环中。外层循环指明正在处理数组的哪一个元素,内层循环找出应存储在元素的值。把这两部分伪代码结合起来,翻译成C代码,就得到了程序清单11.29中的stsrt()函数。顺带一提,C库中有一个更高级的排序函数:qsort()。该函数使用了一个指向函数的指针进行排序比较。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_40186813

你的能量无可限量。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值