Разделение строки на слова с использованием линейного списка - 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;
}

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

Этот код разделяет строку на слова, используя список (или дерево в данном контексте), где каждое слово представлено отдельным узлом. Каждое слово в исходной строке помещается в список в соответствии с его началом (перед первым символом слова) или концом (после последнего символа слова). Список реализован с помощью связного списка, который состоит из узлов, каждый из которых содержит указатель на следующий узел и строку (слово). Вот список действий, которые выполняются в коде:

  1. Инициализация списка в функции slist_init.
  2. Запрос строки у пользователя и сохранение ее в переменной s.
  3. Разделение строки на слова в функции split_word. Каждое слово помещается в список в соответствии с его началом или концом. Функция split_word вызывается с указателем на список в качестве аргумента.
  4. В функции split_word используется цикл, чтобы пройти по каждому символу в строке. Если текущий символ является началом нового слова (не является цифрой), то текущее слово помещается в список. Цикл продолжается до тех пор, пока не будет достигнут конец строки.
  5. После завершения функции split_word строка выводится на экран с помощью цикла for, который проходит по каждому узлу в списке и печатает его содержимое.
  6. Функция slist_clear вызывается для очистки списка и освобождения памяти, занятой узлами списка. Вот список функций, используемых в коде:
  7. slist_init: Инициализирует список.
  8. slist_push_front: Вставляет новый узел в начало списка.
  9. slist_push_back: Вставляет новый узел в конец списка.
  10. slist_clear: Очищает список и освобождает память, занятую узлами списка.
  11. split_word: Разделяет строку на слова и вставляет их в список. Вот список переменных, используемых в коде:
  12. s: Строка, которую нужно разделить на слова.
  13. it: Указатель на текущий узел в списке.
  14. deq: Список, в котором хранятся слова.
  15. h: Переменная-флаг, используемая в цикле в функции split_word. Устанавливается в 1, если текущий символ является началом нового слова.
  16. p: Указатель на текущий символ в строке.
  17. n: Указатель на новый узел, который будет вставлен в список.
  18. t: Указатель на узел, который будет удален из списка в функции slist_clear. Вот список вызовов функций, используемых в коде:
  19. slist_init вызывается в функции main для инициализации списка.
  20. slist_push_front и slist_push_back вызываются в функции split_word для вставки новых узлов в список.
  21. slist_clear вызывается в функции main для очистки списка после того, как все слова были добавлены в список.
  22. printf и fgets используются для вывода строки на экран и чтения строки из стандартного ввода соответственно.

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


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

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

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