Односвязный список: заменить в строке группу рядом стоящих точек на одну точку - C (СИ)
Формулировка задачи:
Решение задачи: «Односвязный список: заменить в строке группу рядом стоящих точек на одну точку»
#include <stdio.h> #include <stdlib.h> #include <string.h> // звено односвязного списка struct node; typedef struct node* node_ptr; struct node { node_ptr link; }; struct list { struct node next; char value; }; typedef struct list* list_ptr; /// возвращает значение верхушки списка char list_top(const list_ptr lst) { return lst->value; } /// добавляет элемент в список struct list *list_push(const list_ptr lst, char value) { list_ptr r; r = (struct list*)malloc(sizeof(struct list)); r->next.link = (node_ptr)lst; r->value = value; return r; } /// удаляет верхушку struct list* list_pop(list_ptr lst) { list_ptr r = NULL; if (lst) { r = (list_ptr)lst->next.link; free(lst); } return r; } /// удаляет список void list_dtor(list_ptr lst) { while (lst != NULL) lst = list_pop(lst); } /// реверс списка. Ваш К.О. list_ptr list_reverse(list_ptr lst) { list_ptr r = NULL, tmp = NULL; while (lst) { tmp = lst; lst = (list_ptr)lst->next.link; tmp->next.link = (node_ptr)r; r = tmp; } return r; } /// собственно основная функция, не забудьте free после использования char* work_func(const char* str) { size_t len = 0; char* r = NULL, *tmp; list_ptr head = NULL; while (*str != 0) { // пока не конец строки switch (*str) { // смотрим текущий символ case '.': // если текущий символ точка if (head) // список не пуст if ('.' == list_top(head)) // и на верхушке точка break; // пропустим его // Да, этот break относится к switch а не к while default: // в остальных случаях добавляем символ в список head = list_push(head, *str); break; } ++str; // перейдем к следующему символу ++len; } head = list_push(head, 0); head = list_reverse(head); r = (char*)malloc(sizeof(char)*(len + 1)); // выделим память под результат tmp = r; // перенос символов в результат while (head) { *tmp = list_top(head); head = list_pop(head); ++tmp; } // вызов деструктора в данном случае не обязателен, но так, для очистки совести list_dtor(head); return r; } /// TODO: написать main int main() { return EXIT_SUCCESS; }
Объяснение кода листинга программы
Код реализует односвязный список, используя структуру звено односвязного списка
и тип данных структура списка
.
Список содержит только один элемент в каждом узле, поэтому каждый узел содержит указатель на следующий узел и значение (в данном случае - символ).
Функция work_func
принимает строку в качестве входного параметра. Проходя по каждому символу строки, она добавляет символы, которые не являются точками, в односвязный список. Если символ является точкой, она пропускает его, если на вершине списка уже есть точка. После обработки всей строки, функция добавляет в список ноль, чтобы указать на конец строки. Затем она инвертирует список, чтобы получить обратное представление строки, и выделяет память под строку, в которую затем переносит символы из списка.
Обратите внимание, что в коде есть несколько свободных операций с памятью, которые не были освобождены. Это может привести к утечкам памяти. Кроме того, код не обрабатывает ситуацию, когда входная строка пуста, что может привести к неопределенному поведению.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д