Разделение строки на слова с использованием линейного списка - C (СИ)
Формулировка задачи:
Разработать программу для обработки строки с использованием линейного списка.Исходная строка вводится с клавиатуры. В строке записаны слова через пробел или несколько пробелов. В начале и концах строк тоже могут быть пробелы. Выделить из строки слова и записать в консольное окно.
Алгоритм выполнения: В строке записаны правильные 8-ричные и 16-ричные константы. На левый конец очереди переписать слова котрые представляют правильные 8-ричные константы, а на правый конец - 16-ричные. Порядок записи констант произвольный.
Решение задачи: «Разделение строки на слова с использованием линейного списка»
textual
Листинг программы
#include <stdio.h>
#include <ctype.h>
#include <malloc.h>
typedef struct _node {
const char* p;
struct _node* next;
} node;
typedef struct {
node* head;
node* tail;
} slist;
void slist_init(slist* lst);
int slist_push_front(slist* lst, const char* p);
int slist_push_back(slist* lst, const char* p);
void slist_clear(slist* lst);
void split_word(slist* lst, char* s){
int h;
char* p;
slist_init(lst);
while(*s){
while(*s && ! isxdigit(*s))
++s;
p = s;
h = 0;
while(isxdigit(*p)){
if(! h)
h = (*p >= '8');
++p;
}
if(*s){
if(*p != '\0')
*p++ = '\0';
if(h)
slist_push_back(lst, s);
else
slist_push_front(lst, s);
}
s = p;
}
}
int main(void){
node* it;
slist deq;
char s[128] = "AB 12 FF 8E AC 78 9A 77 75 DC 10 45 67 CF 33";
/*
printf("enter str: ");
fgets(s, sizeof(s), stdin);
fflush(stdin);
*/
split_word(&deq, s);
//вывести
for(it = deq.head; it != NULL; it = it->next)
printf("%s ", it->p);
slist_clear(&deq);
return 0;
}
//инициализация списка
void slist_init(slist* lst){
lst->head = lst->tail = NULL;
}
//вставка элемента в голову списка
int slist_push_front(slist* lst, const char* p){
node* n = (node*)malloc(sizeof(node));
if(n != NULL){
n->next = NULL;
n->p = p;
if(lst->head == NULL)
lst->head = lst->tail = n;
else {
n->next = lst->head;
lst->head = n;
}
}
return (n != NULL);
}
//вставка элемента в конец списка
int slist_push_back(slist* lst, const char* p){
node* n = (node*)malloc(sizeof(node));
if(n != NULL){
n->next = NULL;
n->p = p;
if(lst->head == NULL)
lst->head = lst->tail = n;
else {
lst->tail->next = n;
lst->tail = n;
}
}
return (n != NULL);
}
//удаление списка
void slist_clear(slist* lst){
node* t;
while(lst->head != NULL){
t= lst->head;
lst->head = lst->head->next;
free(t);
}
lst->tail = NULL;
}
Объяснение кода листинга программы
Этот код разделяет строку на слова, используя список (или дерево в данном контексте), где каждое слово представлено отдельным узлом. Каждое слово в исходной строке помещается в список в соответствии с его началом (перед первым символом слова) или концом (после последнего символа слова).
Список реализован с помощью связного списка, который состоит из узлов, каждый из которых содержит указатель на следующий узел и строку (слово).
Вот список действий, которые выполняются в коде:
- Инициализация списка в функции
slist_init. - Запрос строки у пользователя и сохранение ее в переменной
s. - Разделение строки на слова в функции
split_word. Каждое слово помещается в список в соответствии с его началом или концом. Функцияsplit_wordвызывается с указателем на список в качестве аргумента. - В функции
split_wordиспользуется цикл, чтобы пройти по каждому символу в строке. Если текущий символ является началом нового слова (не является цифрой), то текущее слово помещается в список. Цикл продолжается до тех пор, пока не будет достигнут конец строки. - После завершения функции
split_wordстрока выводится на экран с помощью циклаfor, который проходит по каждому узлу в списке и печатает его содержимое. - Функция
slist_clearвызывается для очистки списка и освобождения памяти, занятой узлами списка. Вот список функций, используемых в коде: slist_init: Инициализирует список.slist_push_front: Вставляет новый узел в начало списка.slist_push_back: Вставляет новый узел в конец списка.slist_clear: Очищает список и освобождает память, занятую узлами списка.split_word: Разделяет строку на слова и вставляет их в список. Вот список переменных, используемых в коде:s: Строка, которую нужно разделить на слова.it: Указатель на текущий узел в списке.deq: Список, в котором хранятся слова.h: Переменная-флаг, используемая в цикле в функцииsplit_word. Устанавливается в1, если текущий символ является началом нового слова.p: Указатель на текущий символ в строке.n: Указатель на новый узел, который будет вставлен в список.t: Указатель на узел, который будет удален из списка в функцииslist_clear. Вот список вызовов функций, используемых в коде:slist_initвызывается в функцииmainдля инициализации списка.slist_push_frontиslist_push_backвызываются в функцииsplit_wordдля вставки новых узлов в список.slist_clearвызывается в функцииmainдля очистки списка после того, как все слова были добавлены в список.printfиfgetsиспользуются для вывода строки на экран и чтения строки из стандартного ввода соответственно.