Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 29.01.2023, 13:01   #1
Saske_Master
Новичок
Джуниор
 
Регистрация: 28.01.2023
Сообщений: 1
Стрелка упорядоченный линейный список

Помогите, пожалуйста, написать программу на "С", расщепляющую упорядоченный линейный список слов на два упорядоченных списка: список со словами, встречающимися ровно 1 раз, и список с оставшимися словами. В итоге, вывести оба списка.

Дополнительные условия:
Программа должна состоять из нескольких функций.
Во всех заданиях располагать узлы списка/дерева в динамической памяти.
Предусмотреть функции вывода на экран списка/дерева.
Разрешены к использованию следующие функции: printf, scanf, getchar (считывание символа с клавиатуры), gets, fgets, malloc, free, fopen, fclose

Заранее очень благодарен за помощь!
Saske_Master вне форума Ответить с цитированием
Старый 04.02.2023, 23:17   #2
Пётр Седов
Форумчанин
 
Регистрация: 26.10.2022
Сообщений: 119
По умолчанию

Код:
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

/* структура переменного размера */
struct word_t {
  struct word_t* next;
  char elems[1]; /* на самом деле длина будет не 1; это поле должно быть последним в структуре */
};

struct word_list_t {
  struct word_t* first;
  struct word_t* last;
};

struct word_t* create_word(const char* text) {
  struct word_t* w;
  int len;

  len = strlen(text);
  /* выделяем блок памяти в heap-е */
  w = (struct word_t*)malloc(offsetof(struct word_t, elems) + len + 1); /* sizeof(char) = 1, по определению языка C */
  if (w == NULL) { /* если не получилось выделить блок памяти */
    /* упрощённая обработка ошибки */
    printf("Cannot allocate memory block.\n");
    exit(1);
  }
  w->next = NULL;
  memcpy(w->elems, text, len + 1); /* копируем вместе с завершающим нулевым элементом ('\0') */
  return w;
}

/* добавляет слово в конец списка */
void add(struct word_list_t* list, struct word_t* word) {
  word->next = NULL;
  if (list->last != NULL) {
    list->last->next = word;
  } else {
    list->first = word;
  }
  list->last = word;
}

/* вставляет слово в сортированный список */
void insert(struct word_list_t* list, struct word_t* word) {
  struct word_t* prev;
  struct word_t* next;

  /* ищем подходящее место для вставки */
  prev = NULL;
  next = list->first;
  while (next != NULL) {
    if (strcmp(word->elems, next->elems) < 0) {break;}
    prev = next;
    next = next->next;
  }

  /* вставляем слово */
  word->next = next;
  if (prev != NULL) {
    prev->next = word;
  } else {
    list->first = word;
  }
  if (next == NULL) {
    list->last = word;
  }
}

void clear(struct word_list_t* list) {
  struct word_t* w;
  struct word_t* w2;

  for (w = list->first; w != NULL; w = w2) {
    w2 = w->next;
    free(w); /* освобождаем блок памяти */
  }
  list->first = list->last = NULL;
}

/* words должен быть сортированным списком */
void split(struct word_list_t* words, struct word_list_t* unique_words, struct word_list_t* repeating_words) {
  struct word_t* w;
  struct word_t* w2;

  assert(unique_words->first == NULL); /* список должен быть пустой */
  assert(repeating_words->first == NULL); /* список должен быть пустой */
  w = words->first;
  while (w != NULL) {
    w2 = w->next;
    if ((w2 != NULL) && (strcmp(w2->elems, w->elems) == 0)) { /* если два одинаковых слова подряд */
      add(repeating_words, w);
      do {
        w = w2;
        w2 = w2->next;
        add(repeating_words, w);
      } while ((w2 != NULL) && (strcmp(w2->elems, w->elems) == 0));
    } else {
      add(unique_words, w);
    }
    w = w2;
  }
  words->first = words->last = NULL;
}

void print(const struct word_list_t* list) {
  const struct word_t* w;

  for (w = list->first; w != NULL; w = w->next) {
    printf("%s ", w->elems);
  }
  printf("\n");
}

int main() {
  struct word_list_t words = {NULL, NULL};
  struct word_list_t unique_words = {NULL, NULL};
  struct word_list_t repeating_words = {NULL, NULL};

  insert(&words, create_word("print"));
  insert(&words, create_word("and"));
  insert(&words, create_word("zoom"));
  insert(&words, create_word("and"));
  insert(&words, create_word("clone"));
  insert(&words, create_word("and"));
  insert(&words, create_word("block"));
  insert(&words, create_word("and"));
  insert(&words, create_word("abort"));
  split(&words, &unique_words, &repeating_words);
  printf("Unique words: ");
  print(&unique_words);
  printf("Repeating words: ");
  print(&repeating_words);
  assert(words.first == NULL); /* список должен быть пустой */
  clear(&unique_words);
  clear(&repeating_words);
  return 0;
}
Вывод на консоль:
Код:
Unique words: abort block clone print zoom
Repeating words: and and and and
Цитата:
Сообщение от Saske_Master Посмотреть сообщение
Разрешены к использованию следующие функции: printf, scanf, getchar (считывание символа с клавиатуры), gets, fgets, malloc, free, fopen, fclose
Я использовал стандартные функции exit, strlen, memcpy, strcmp и стандартные макросы assert, offsetof. Они не входят в список разрешённых, но попробуйте так, а если не получится, можно будет что-нибудь переделать.
Пётр Седов вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
C++ / упорядоченный список /удаление дубликата через уже после занесения vorastra Помощь студентам 1 10.01.2018 05:04
Двунаправленный упорядоченный по убыванию список desdim Паскаль, Turbo Pascal, PascalABC.NET 1 08.04.2017 11:07
дан упорядоченный список названия книг MDragniil Общие вопросы C/C++ 1 28.12.2016 08:42
(C++) Упорядоченный список & таблица в двоичном файле annussaa Общие вопросы C/C++ 0 01.05.2015 19:00
Создать общий упорядоченный список, используя имеющуюся частичную сортировку. Roma1305 Паскаль, Turbo Pascal, PascalABC.NET 0 14.11.2012 18:25