ПРИМЕР: СОРТИРОВКА СТРОК
ПРИМЕР: СОРТИРОВКА СТРОК
Возьмем реальную задачу сортировки строк в алфавитном порядке. Эта задача может возникнуть при подготовке списка фамилий, при создании алфавитного указателя и во многих других ситуациях. В такой программе одним из главных инструментов является функция strcmp( ), так как ее можно использовать для определения старшинства двух строк. Последовательность наших действий будет состоять из считывания массива строк, их сортировки и последующего вывода. Совсем недавно мы показали последовательность действий для считывания строк, и сейчас мы начнем программу таким же образом.
/* считывает строки и сортирует их */
#include <stdio.h>
#define SIZE 81 /* предельная длина строки, включая */
#define LIM 20 /* максимальное количество считываемых строк */
#define HALT " " /* нулевая строка для прекращения ввода */
main( )
{
static char input[LIM][SIZE]; /* массив для запоминания вводимых строк */
char *ptstr[LIM]; /* массив переменных типа указатель */
int ct = 0; /* счетчик вводимых строк */
int k; /* счетчик выводимых строк */
printf(" Введите до %d строк и я их отсортирую. " , LIM);
printf(" Для прекращения ввода нажмите клавишу [ввод] в начале строки. ");
while((gets(input[ct])!= NULL) && strcmp(input[ct], HALT)
!= 0 && ct++ < LIM)
ptstr[ct - 1] = input[ct - 1]; /*указывает на еще не
отсортированный ввод */
stsrt(ptstr, ct); /* сортировка строк */
puts(" Вот отсортированный список строк: ");
for(k = 0; k < ct; k++)
puts(ptstr[k]); /* указатели на отсортированные строки */
}
/* функция сортировки-строк-с-использованиeм-указатeлeй */
stsrt(strings, num)
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;
} }
РИС. 13.4. Программа чтения и сортировки строк.
Вывод строк на печать не составляет проблемы, а для сортировки можно взять тот же алгоритм, который использовался раньше для чисел. Сейчас мы применим один хитрый трюк: посмотрим, сможете ли вы его заметить.
Для проверки возьмем детский стишок.
Введите 20 строк, и я их отсортирую.
Для прекращения ввода нажмите клавишу [ввод] в начале строки.
Жил на свете человек
Скрюченные ножки
И гулял он целый век
По скрюченной дорожке
Вот отсортированный список строк
Жил на свете человек
И гулял он целый век
По скрюченной дорожке
Скрюченные ножки
Детские стишки не кажутся слишком искаженными после сортировки их по алфавиту.
Трюк состоит в том что вместо перегруппировки самих строк мы перегруппировали их указатели. Разберемся в этом. В начале ptrst[0] ссылается на input[0] и т. д. Каждый input[ ] является массивом из 81 элемента, а каждый элемент ptrst[ ] является отдельной переменной. Процедура сортировки перегруппировывает ptrst, нe трогая input. Если, например, input[l] стоит перед input[0] по алфавиту, то программа переключает указатели ptrst, в результате чего ptrst[0] ссылается на input[1], a ptrst[1] на input[0]. Это гораздо легче, чем, используя strcpy( ), менять местами две введенные строки. Просмотрите еще раз этот процесс на рисунке.
И наконец, давайте попытаемся заполнить пробелы, оставшиеся в нашем описании, а именно "пустоту" между скобками в функции main( ).