Если слово встретилось первый раз, то для него добавляется новый элемент в конец списка - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Разработайте программу, которая читает из стандартного потока ввода слова и размещает их в связный список следующим образом. Если слово встретилось первый раз, то для него добавляется новый элемент в конец списка. В противном случае в соответствующем элементе списка увеличивается счетчик слов. Элемент списка — структура, имеющая следующие поля: слово, количество повторений данного слова в потоке, указатель на следующий элемент списка. После окончания ввода содержимое списка выводится в стандартный поток вывода. Измените программу так, чтобы список стал двусвязным. Выведите список в прямом и обратном направлении. Нужно как бы две программы. Помогите пожалуйста!!

Решение задачи: «Если слово встретилось первый раз, то для него добавляется новый элемент в конец списка»

textual
Листинг программы
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
typedef struct NODE {
    char * wrd;
    size_t cnt;
    struct NODE * next;
} node_t;
 
int push_word(node_t ** pList, const char * wrd) {
    if ( ! *pList ) {
        if ( ! ( *pList = malloc(sizeof(node_t)) ) )
            return -1;
        if ( ! ( (*pList)->wrd = malloc(strlen(wrd) + 1) ) )
            return -1;
        strcpy((*pList)->wrd, wrd);
        (*pList)->cnt = 1;
        (*pList)->next = NULL;
        return 0;
    }
    else if ( ! strcmp((*pList)->wrd, wrd) ) {
        (*pList)->cnt += 1;
        return 0;
    }
    else
        return push_word(&((*pList)->next), wrd);
}
 
void dump_list(const node_t * list) {
    while ( list ) {
        printf("%s\t%lu\n", list->wrd, list->cnt);
        list = list->next;
    }
}
 
void del_list(node_t ** pList) {
    while ( *pList ) {
        node_t * next = (*pList)->next;
        free((*pList)->wrd);
        free(*pList);
        *pList = next;
    }
}
 
#define DELIM " \t\n"
 
int main(void) {
    char buf[BUFSIZ];
    
    while ( printf("String: ") && fgets(buf, BUFSIZ, stdin) && *buf != '\n' ) {
        char * ptr;
        node_t * list;
        
        for ( list = NULL, ptr = strtok(buf, DELIM); ptr; ptr = strtok(NULL, DELIM) ) {
            if ( push_word(&list, ptr) ) {
                fprintf(stderr, "Memory error!\n");
                exit(1);
            }
        }
        
        dump_list(list);
        del_list(&list);
    }
    
    exit(0);
}

Объяснение кода листинга программы

  1. Структура данных, используемая в программе, это связанный список (linked list).
  2. Упомянутая структура имеет следующие поля:
    • char * wrd: указатель на строку (word) в памяти.
    • size_t cnt: счетчик (counter) количества вхождений слова в список.
    • struct NODE * next: указатель на следующий элемент в списке.
  3. Функция push_word() добавляет новое слово в список. Если список пуст, функция выделяет память под новый узел (node) и добавляет его в начало списка. В противном случае, функция проверяет, есть ли уже данное слово в списке. Если слово уже присутствует, функция увеличивает счетчик (counter) на 1. Если слово отсутствует, функция вызывает саму себя для добавления слова в следующую часть списка.
  4. Функция dump_list() выводит содержимое списка на экран.
  5. Функция del_list() освобождает память, выделенную под каждый узел списка.
  6. В функции main() программа запрашивает строку у пользователя и разбивает ее на слова. Затем для каждого слова вызывается функция push_word(). После добавления всех слов в список, список выводится на экран, а затем освобождается память, выделенная под список.
  7. Если во время выполнения программы происходит ошибка выделения памяти, программа выводит сообщение об ошибке и завершает свое выполнение с кодом 1.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

13   голосов , оценка 3.769 из 5
Похожие ответы