Связные списки (?) Отсортировать карточки с названиями мест по первой букве - C (СИ)
Формулировка задачи:
Есть студенты, есть большое количество карточек, на каторых написаны названия мест, куда их нужно разослать. Их нужно отсортировать по местам, куда они будут отправлены.
Вопрос в том, как большое кол-во карточек отсортировать по местам проживания? Было предложено сначала отсортировать все карточки по первой букве названия места проживания. Затем будет легче отсортировать по самим местам проживания. Была предложена следующая процедура для первого этапа:
1)Каждой букве латинского алфавита - по одному студенту (нужны 26 студентов)
2)Карточки должны лежать на движущейся ленте или ее аналоге, вдоль которой стоят студенты, которые занимаются сортировкой карточек.
3)Каждый студент берет с ленты предназначенную ему карточку, т.е. карточку, адрес места жительства которой начинается с буквы, которая у конкретного студента. Все большие буквы будут считаться за маленькие.
4)Студент взятые карточки по порядку кладет в одну стопку
5)Потом, когда все карточки на ленте закончатся, студенты берут по одной карточке из своей стопки и кладут на движущуюся ленту, чтобы отправить ее на следующий этап сортировки.
6)Студенты кладут карточки по алфавитному порядку (т.е. сначала все свои карточки кладет студент с буквой "а", потом следующие по алфавиту до "z"
Написать программу симуляции этого процесса.
Запрограммировать результаты работы первого этапа. На вводе - файл, который содержит места проживания (одно слово длиной [1..255], только маленькие буквы латинского алфавита [a...z]. Места проживания отделены одним или более чем одним пробелом.
Решение задачи: «Связные списки (?) Отсортировать карточки с названиями мест по первой букве»
textual
Листинг программы
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> /* Каждой фигне - свой тип данных */ typedef char town_t[256]; /* А так будем названия городов из файла читать, закладываясь на то, что они или из одного * слова, или из разделённых чёрточой без пробелов */ #define get_name_from_file(f, n) ( fscanf((f), "%255s", (n)) == 1 ) /* Для полной реалистичности поделим на объекты всё, что можно, к томуже может пригодиться */ typedef struct ADDRESS { town_t town; /*street, buildlng, appts, etc... */ } address_t; /* Письмо */ typedef struct LETTER { address_t address; /* recipient, sender... */ } letter_t; /* Держалки для писем */ typedef struct HOLDER { letter_t * letter; struct HOLDER * next; } holder_t, * stack_t; /* Есть пара нюансов: * во-первых названия городов принято с большой буквы писать, так и будем делать * во-вторых письма проще хранить в стеке, а собирать тоже в стек, но от * поседнего к первому, тогда в общем стеке на выходе письма будут отсортированы * по первой букве названия города по алфавиту */ /* Функции для работы со всем этим счастьем */ /* Контруктор для нового письма. В таком виде принимает только название города, * легко расширяется при необходимости */ letter_t * new_letter(town_t town) { letter_t * letter = malloc(sizeof(letter_t)); if ( ! letter ) return NULL; strcpy(letter->address.town, town); *(letter->address.town) = toupper(*(letter->address.town)); return letter; } void del_letter(letter_t * letter) { free(letter); } const char * get_town_name(const letter_t * letter) { return letter->address.town; } holder_t * new_holder(letter_t * letter) { holder_t * holder = malloc(sizeof(holder_t)); if ( ! holder ) return NULL; holder->letter = letter; holder->next = NULL; return holder; } void del_holder(holder_t * holder) { del_letter(holder->letter); free(holder); } /* Помещает держалку с письмом в стек */ void stack_put(stack_t * pStack, holder_t * pHolder) { pHolder->next = *pStack; *pStack = pHolder; } /* Удаляет держалку с письмом из стека, если она там есть. * Возвращает держалку или NULL */ holder_t * stack_get(stack_t * pStack) { if ( ! *pStack ) return NULL; else { holder_t * holder = *pStack; *pStack = (*pStack)->next; holder->next = NULL; /* отвязываем держалку от стека */ return holder; } } /* Почтальоны */ typedef struct POSTMAN { char watchingChar; stack_t stack; /* name, shoe_size, etc... */ } postman_t; postman_t * new_postman(char watchingChar) { postman_t * postman = malloc(sizeof(postman_t)); if ( ! postman ) return NULL; postman->watchingChar = watchingChar; postman->stack = NULL; return postman; } void del_postman(postman_t * postman) { while ( postman->stack ) { holder_t * holder = stack_get(&(postman->stack)); del_holder(holder); } free(postman); } /* Проверка того, что письмо должно быть обработано почтальоном */ int wow_is_mine(postman_t * postman, letter_t * letter) { return ( *get_town_name(letter) == postman->watchingChar ); } /* Поместить письмо в держалке в стек почтальона */ void postman_put(postman_t * postman, holder_t * holder) { stack_put(&(postman->stack), holder); } /* Забрать письмо */ holder_t * postman_get(postman_t * postman) { return stack_get(&(postman->stack)); } /*********************************************************************************** ******************** PROGRAM ABOUT POSTMEN AND SO ******************************** ******************** **************************************************************/ #define ALL_POSTMEN ( 'Z' - 'A' + 1 ) #define TOWNS_FILE_NAME "towns.txt" /* должен быть в одной папке с программой */ int main(void) { FILE * fin; postman_t * postmen[ALL_POSTMEN]; stack_t allLetters; town_t currentTown; letter_t * currentLetter; holder_t * currentHolder; int i; /* Плодим почтальонов */ for ( i = 0; i < ALL_POSTMEN; ++i ) { if ( ! ( postmen[i] = new_postman('A' + i) ) ) { fprintf(stderr, "Memory error in new_postman!\n"); exit(1); } } /* Открываем файл */ if ( ! ( fin = fopen(TOWNS_FILE_NAME, "r") ) ) { fprintf(stderr, "Can't open input file!\n"); for ( i = 0; i < ALL_POSTMEN; ++i ) del_postman(postmen[i]); exit(1); } /* Читаем из файла по одному названию города, делаем из них письма, * распределяем между почтальонами */ while ( get_name_from_file(fin, currentTown) ) { if ( ! ( currentLetter = new_letter(currentTown) ) ) { fprintf(stderr, "Memory error in new_letter!\n"); if ( fclose(fin) ) perror("fclose"); exit(1); } for ( i = 0; i < ALL_POSTMEN; ++i ) { if ( wow_is_mine(postmen[i], currentLetter) ) { if ( ! ( currentHolder = new_holder(currentLetter) ) ) { fprintf(stderr, "Memory error in new_holder!\n"); if ( fclose(fin) ) perror("fclose"); exit(1); } postman_put(postmen[i], currentHolder); break; } } if ( i == ALL_POSTMEN ) { fprintf(stderr, "Unknown town name: %s\n", get_town_name(currentLetter)); del_letter(currentLetter); } } if ( ferror(fin) || fclose(fin) ) { fprintf(stderr, "Something is wrong with input file!\n"); exit(1); } allLetters = NULL; for ( i = ALL_POSTMEN - 1; i >= 0; --i ) { while ( currentHolder = postman_get(postmen[i]) ) stack_put(&allLetters, currentHolder); del_postman(postmen[i]); } printf("All letter targets sorted by first character:\n"); while ( currentHolder = stack_get(&allLetters) ) { printf("%s\n", get_town_name(currentHolder->letter)); del_holder(currentHolder); } exit(0); }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д