diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..84ea374 --- /dev/null +++ b/.clang-format @@ -0,0 +1,244 @@ +--- +Language: Cpp +# BasedOnStyle: WebKit +AccessModifierOffset: -4 +AlignAfterOpenBracket: DontAlign +AlignArrayOfStructures: None +AlignConsecutiveAssignments: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: true +AlignConsecutiveBitFields: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveDeclarations: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveMacros: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveShortCaseStatements: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCaseColons: false +AlignEscapedNewlines: Right +AlignOperands: DontAlign +AlignTrailingComments: + Kind: Never + OverEmptyLines: 0 +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowBreakBeforeNoexceptSpecifier: Never +AllowShortBlocksOnASingleLine: Empty +AllowShortCaseLabelsOnASingleLine: false +AllowShortCompoundRequirementOnASingleLine: true +AllowShortEnumsOnASingleLine: true +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: MultiLine +AttributeMacros: + - __capability +BinPackArguments: true +BinPackParameters: true +BitFieldColonSpacing: Both +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterExternBlock: false + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakAdjacentStringLiterals: true +BreakAfterAttributes: Leave +BreakAfterJavaFieldAnnotations: false +BreakArrays: true +BreakBeforeBinaryOperators: All +BreakBeforeConceptDeclarations: Always +BreakBeforeBraces: WebKit +BreakBeforeInlineASMColon: OnlyMultiline +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeComma +BreakInheritanceList: BeforeColon +BreakStringLiterals: true +ColumnLimit: 0 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: false +DerivePointerAlignment: false +DisableFormat: false +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: false +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IfMacros: + - KJ_IF_MAYBE +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + CaseSensitive: false + - Regex: '.*' + Priority: 1 + SortPriority: 0 + CaseSensitive: false +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentAccessModifiers: false +IndentCaseBlocks: false +IndentCaseLabels: false +IndentExternBlock: AfterExternBlock +IndentGotoLabels: true +IndentPPDirectives: None +IndentRequiresClause: true +IndentWidth: 4 +IndentWrappedFunctionNames: false +InsertBraces: false +InsertNewlineAtEOF: false +InsertTrailingCommas: None +IntegerLiteralSeparator: + Binary: 0 + BinaryMinDigits: 0 + Decimal: 0 + DecimalMinDigits: 0 + Hex: 0 + HexMinDigits: 0 +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +KeepEmptyLinesAtEOF: false +LambdaBodyIndentation: Signature +LineEnding: DeriveLF +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: Inner +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 4 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: true +ObjCSpaceBeforeProtocolList: true +PackConstructorInitializers: BinPack +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakOpenParenthesis: 0 +PenaltyBreakScopeResolution: 500 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyIndentedWhitespace: 0 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Left +PPIndentWidth: -1 +QualifierAlignment: Leave +ReferenceAlignment: Pointer +ReflowComments: true +RemoveBracesLLVM: false +RemoveParentheses: Leave +RemoveSemicolon: false +RequiresClausePosition: OwnLine +RequiresExpressionIndentation: OuterScope +SeparateDefinitionBlocks: Leave +ShortNamespaceLines: 1 +SkipMacroDefinitionBody: false +SortIncludes: CaseSensitive +SortJavaStaticImport: Before +SortUsingDeclarations: LexicographicNumeric +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceAroundPointerQualifiers: Default +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: true +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeJsonColon: false +SpaceBeforeParens: ControlStatements +SpaceBeforeParensOptions: + AfterControlStatements: true + AfterForeachMacros: true + AfterFunctionDefinitionName: false + AfterFunctionDeclarationName: false + AfterIfMacros: true + AfterOverloadedOperator: false + AfterPlacementOperator: true + AfterRequiresInClause: false + AfterRequiresInExpression: false + BeforeNonEmptyParentheses: false +SpaceBeforeRangeBasedForLoopColon: true +SpaceBeforeSquareBrackets: false +SpaceInEmptyBlock: true +SpacesBeforeTrailingComments: 1 +SpacesInAngles: Never +SpacesInContainerLiterals: true +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: -1 +SpacesInParens: Never +SpacesInParensOptions: + InCStyleCasts: false + InConditionalStatements: false + InEmptyParentheses: false + Other: false +SpacesInSquareBrackets: false +Standard: Latest +StatementAttributeLikeMacros: + - Q_EMIT +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseTab: Never +VerilogBreakBetweenInstancePorts: true +WhitespaceSensitiveMacros: + - BOOST_PP_STRINGIZE + - CF_SWIFT_NAME + - NS_SWIFT_NAME + - PP_STRINGIZE + - STRINGIZE \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..c8b06bf --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.25) + +project(C_Homework C) + +add_subdirectory(src/listLesson) + +add_compile_options(-Wall -Wextra -Wpedantic) \ No newline at end of file diff --git a/src/listLesson/CMakeLists.txt b/src/listLesson/CMakeLists.txt new file mode 100644 index 0000000..0b2ed5e --- /dev/null +++ b/src/listLesson/CMakeLists.txt @@ -0,0 +1,11 @@ +add_library(list list.c) + +add_library(cyclicList cyclicList.c) + +add_executable(counting counting.c) + +add_executable(sortedListTask sortedListTask.c) + +target_link_libraries(sortedListTask PRIVATE list) + +target_link_libraries(counting PRIVATE cyclicList) \ No newline at end of file diff --git a/src/listLesson/counting.c b/src/listLesson/counting.c new file mode 100644 index 0000000..2753bc4 --- /dev/null +++ b/src/listLesson/counting.c @@ -0,0 +1,18 @@ +#include "cyclicList.h" +#include "list.h" +#include +#include + +int main() +{ + printf("Введите n и m через пробел\n"); + int n = 0; + int m = 0; + scanf("%d %d", &n, &m); + List* list = newList(); + for (int i = 1; i <= n; i++) { + insert(list, i - 1, i); + } + printf("%d\n", findTheSafeIndex(list, m)); + return 0; +} diff --git a/src/listLesson/cyclicList.c b/src/listLesson/cyclicList.c new file mode 100644 index 0000000..9c31a5f --- /dev/null +++ b/src/listLesson/cyclicList.c @@ -0,0 +1,171 @@ +#include "cyclicList.h" +#include "stdio.h" +#include +#include + +// структура обычного элемента в списке +typedef struct ListNode ListNode; + +typedef struct ListNode { + int value; + ListNode* next; + +} ListNode; + +typedef struct List { + ListNode* head; +} List; + +List* newList() +{ + List* new = calloc(1, sizeof(*new)); + return new; +} + +bool insert(List* list, int index, int value) +{ + if (list == NULL) { + return false; + } + if (isEmpty(list)) { + ListNode* newNode = calloc(1, sizeof(ListNode)); + newNode->value = value; + newNode->next = newNode; + list->head = newNode; + return true; + } + if (index == 0) { + ListNode* newNode = calloc(1, sizeof(ListNode)); + newNode->value = value; + ListNode* current = list->head; + while (current->next != list->head) { + current = current->next; + } + newNode->next = list->head; + list->head = newNode; + current->next = newNode; + return true; + } + + ListNode* current = list->head; + int counter = 0; + // условия для while нет, чтобы пользователь мог вставлять элемент на любой + // индекс (так как список цикличный, ему нет разницы какой индекс указали) + while (1) { + if (counter == index - 1) { + ListNode* newNode = calloc(1, sizeof(ListNode)); + newNode->value = value; + newNode->next = current->next; + current->next = newNode; + return true; + } + current = current->next; + counter++; + } + return false; +} + +bool removeElement(List* list, int index) +{ + if (list == NULL || isEmpty(list)) { + return false; + } + + if (index == 0) { + ListNode* elemToRemove = list->head; + if (elemToRemove->next == elemToRemove) { + free(elemToRemove); + list->head = NULL; + return true; + } + + ListNode* current = list->head; + while (current->next != elemToRemove) { + current = current->next; + } + list->head = elemToRemove->next; + current->next = list->head; + free(elemToRemove); + return true; + } + + ListNode* current = list->head; + int counter = 0; + // условия для while нет, чтобы пользователь мог вставлять элемент на любой + // индекс (так как список цикличный, ему нет разницы какой индекс указали) + while (1) { + if (counter == index - 1) { + ListNode* nodeToDelete = current->next; + current->next = nodeToDelete->next; + free(nodeToDelete); + return true; + } + current = current->next; + counter++; + } + return false; +} + +bool deleteList(List* list) +{ + if (list == NULL || isEmpty(list)) { + return false; + } + while (!isEmpty(list)) { + removeElement(list, 0); + } + free(list); + return true; +} + +bool isEmpty(List* list) { return list->head == NULL; } + +bool oneElement(List* list) { return list->head->next == list->head; } + +void printList(List* list) +{ + if (list == NULL || isEmpty(list)) { + printf("Список пустой\n"); + return; + } + ListNode* current = list->head; + do { + printf("%d ", current->value); + current = current->next; + } while (current != list->head); + printf("\n"); +} + +int getLength(List* list) +{ + if (list == NULL || isEmpty(list)) { + return -1; + } + int counter = 0; + ListNode* current = list->head; + do { + counter++; + current = current->next; + } while (current != list->head); + return counter; +} + +int findTheSafeIndex(List* list, int m) +{ + ListNode* current = list->head; + ListNode* prev = NULL; + while (!oneElement(list)) { + for (int i = 0; i < m; i++) { + prev = current; + current = current->next; + } + if (current == list->head) { + list->head = current->next; + } + + prev->next = current->next; + free(current); + current = prev->next; + } + return list->head->value; +} diff --git a/src/listLesson/cyclicList.h b/src/listLesson/cyclicList.h new file mode 100644 index 0000000..c383093 --- /dev/null +++ b/src/listLesson/cyclicList.h @@ -0,0 +1,76 @@ +#pragma once +#include + +// структура содержащая указатель на первый элемент списка +typedef struct List List; + +/* + * функция создания нового списка + * ничего не принимает + * возвращает указатель на объект типа List + */ +List* newList(); + +/* + * функция вставки элемента по заданному индексу + * принимает на вход указатель на объект типа List, желаемый индекс и значение + * возвращает булевое значение, сообщающее, удачно ли прошла операция + */ +bool insert(List* list, int index, int value); + +/* + * функция удаления элемента по индексу + * принимает указатель на объект типа List и индекс элемента + * возвращает булевое значние, сообщающее, удачно ли прошла операция + * внутри себя освобождает память удаляемого элемента + */ +bool removeElement(List* list, int index); + +/* + * функция удаления всего списка + * принимает указатель на объект типа List + * внутри себя вызывает функцию removeElement + * возвращает булевое значение, удачно ли прошла операция + */ +bool deleteList(List* list); + +/* + * функция проверки, пустой ли список + * возвращает true если пустой, false, если нет + * на вход принимает указатель на список + */ +bool isEmpty(List* list); + +/* + * функция проверки, один ли элемент в списке + * возвращает true если да, false, если нет + * на вход принимает указатель на список + */ +bool oneElement(List* list); + +/* + * функция вывода списка в консоль + * принимает только указаетль на первый элемент списка, + * ничего не возвращает + * печатает элементы списка через пробел + * в случае переданного пустого или несуществующего списка сообщает об этом + * пользователю + */ +void printList(List* list); + +/* + * функция, возвращающая длину списка + * принимает на вход указатель на список + * проходится по всем элементам + * возвращает его длину + */ +int getLength(List* list); + +/* + * функция алгоритма Иосифа + * на вход принимает указатель на объект типа List и m (каждого m-того война + * будут убивать) возвращает значение последнего оставшегося элемента - места, + * куда нужно встать, по условию задачи функция создана исключительно для + * реализации алгоритма из файла counting.c. + */ +int findTheSafeIndex(List* list, int m); diff --git a/src/listLesson/list.c b/src/listLesson/list.c new file mode 100644 index 0000000..eb86229 --- /dev/null +++ b/src/listLesson/list.c @@ -0,0 +1,169 @@ +#include "list.h" +#include +#include +#include + +typedef struct ListNode ListNode; + +// структура обычного элемента в списке +struct ListNode { + int value; + struct ListNode* next; +}; + +// структура содержащая указатель на первый элемент списка +struct List { + ListNode* head; +}; + +List* newList() +{ + List* list = calloc(1, sizeof(*list)); + return list; +} + +bool insert(List* list, int index, int value) +{ + if (list == NULL || index < 0) { + return false; + } + if (index == 0) { + ListNode* newNode = malloc(sizeof(ListNode)); + newNode->value = value; + newNode->next = list->head; + list->head = newNode; + return true; + } + ListNode* current = list->head; + int counter = 0; + while (current != NULL) { + if (counter == index - 1) { + ListNode* newNode = malloc(sizeof(ListNode)); + newNode->value = value; + newNode->next = current->next; + current->next = newNode; + return true; + } + current = current->next; + counter++; + } + return false; +} +// а что если пользователь ошибся?? ввел не тот индекс например? что возвращать? +int get(List* list, int index) +{ + if (list == NULL || isEmpty(list) || index < 0) + return -1; + if (index == 0) { + return list->head->value; + } + ListNode* current = list->head; + int counter = 0; + while (current != NULL) { + if (counter == index) { + return current->value; + } + current = current->next; + counter++; + } + return -1; +} + +bool removeElement(List* list, int index) +{ + if (list == NULL || isEmpty(list) || index < 0) { + return false; + } + ListNode* current = list->head; + if (index == 0) { + list->head = current->next; + free(current); + return true; + } + int counter = 0; + while (current != NULL) { + if (counter == index - 1) { + if (current->next == NULL) + return false; + ListNode* nodeToDelete = current->next; + current->next = nodeToDelete->next; + free(nodeToDelete); + return true; + } + current = current->next; + counter++; + } + return false; +} + +bool deleteList(List* list) +{ + if (list == NULL || isEmpty(list)) { + return false; + } + while (!isEmpty(list)) { + removeElement(list, 0); + } + free(list); + return true; +} + +void printList(List* list) +{ + if (list == NULL || isEmpty(list)) { + printf("Список пустой\n"); + return; + } + + ListNode* current = list->head; + while (current != NULL) { + printf("%d ", current->value); + current = current->next; + } + printf("\n"); +} + +bool isEmpty(List* list) { return list->head == NULL; } + +bool insert_sorted_in_ascending_order(List* list, int value) +{ + if (list == NULL) { + return false; + } + // случай еще незаполненного списка + if (isEmpty(list)) { + return insert(list, 0, value); + } + ListNode* current = list->head; + int counter = 0; + // если элемент самый маленький и его надо вставить в начало + if (current->value > value) { + return insert(list, 0, value); + } + while (current != NULL && current->next != NULL) { + if ((current->next->value > value) && (current->value <= value)) { + return (insert(list, counter + 1, value)); + } + current = current->next; + counter++; + } + // если программа достигла этой строчки, то значит что элемент больше всех + // остальных + return insert(list, counter + 1, value); +} + +int getLength(List* list) +{ + if (list == NULL || isEmpty(list)) { + return -1; + } + int counter = 0; + ListNode* current = list->head; + do { + counter++; + current = current->next; + } while (current != NULL); + return counter; +} + +bool oneElement(List* list) { return list->head->next == NULL; } diff --git a/src/listLesson/list.h b/src/listLesson/list.h new file mode 100644 index 0000000..377a36d --- /dev/null +++ b/src/listLesson/list.h @@ -0,0 +1,89 @@ +#pragma once +#include + +// структура содержащая указатель на первый элемент списка +typedef struct List List; + +/* + * функция создания нового списка + * ничего не принимает + * возвращает указатель на объект типа List + */ +List* newList(); + +/* + * функция вставки элемента по заданному индексу + * принимает на вход указатель на объект типа List, желаемый индекс и значение + * возвращает булевое значение, сообщающее, удачно ли прошла операция + */ +bool insert(List* list, int index, int value); + +/* + * функция просмотра элемента списка по индексу + * принимает указатель на объект типа List и индекс + * возвращает value элемента + * если что-то пошло не так, вернет -1 + */ +int get(List* list, int index); + +/* + * функция удаления элемента по индексу + * принимает указатель на объект типа List и индекс элемента + * возвращает булевое значние, сообщающее, удачно ли прошла операция + * внутри себя освобождает память удаляемого элемента + */ +bool removeElement(List* list, int index); + +/* + * функция соединения двух списков + * подразумевается, что пользователь передает в ф. два существующих непустых списка + * возвращает указатель типа List на первый элемент первого переданного списка + * !!на данный момент нуждается в доработке!! + */ +List* appendLists(List* list1, List* list2); + +/* + * функция удаления всего списка + * принимает указатель на объект типа List + * внутри себя вызывает функцию removeElement + * возвращает булевое значение, удачно ли прошла операция + */ +bool deleteList(List* list); + +/* + * функция вывода списка в консоль + * принимает только указаетль на список + * ничего не возвращает + * печатает элементы списка через пробел + * в случае переданного пустого или несуществующего списка сообщает об этом пользователю + */ +void printList(List* list); + +/* + * функция которая вставляет элемент в определенное место так, чтобы список всегда оставался отсортированным + * принимает значение и список + * возвращает булевое значение об успешной или неуспешной вставке + */ +bool insert_sorted_in_ascending_order(List* list, int value); + +/* + * функция проверки, пустой ли список + * возвращает true если пустой, false, если нет + * на вход принимает указатель на список + */ +bool isEmpty(List* list); + +/* + * функция, возвращающая длину списка + * принимает на вход указатель на список + * проходится по всем элементам + * возвращает его длину + */ +int getLength(List* list); + +/* + * функция проверки, один ли элемент в списке + * возвращает true если да, false, если нет + * на вход принимает указатель на список + */ +bool oneElement(List* list); diff --git a/src/listLesson/sortedListTask.c b/src/listLesson/sortedListTask.c new file mode 100644 index 0000000..789eef1 --- /dev/null +++ b/src/listLesson/sortedListTask.c @@ -0,0 +1,99 @@ +#include "list.h" +#include +#include + +void printMenu() +{ + printf("\n=== МЕНЮ КОМАНД ===\n"); + printf("1 - Добавить элемент (с сортировкой по возрастанию)\n"); + printf("2 - Удалить элемент по индексу\n"); + printf("3 - Вывести список\n"); + printf("0 - Выход из программы\n"); +} + +void clearInputBuffer() +{ + int c; + while ((c = getchar()) != '\n') { } +} + +void addElementInList(List* list) +{ + int element = 0; + printf("Введите элемент который хотите добавить\n"); + + if (scanf("%d", &element) != 1) { + printf("Ошибка: введено некорректное значение!\n"); + clearInputBuffer(); + return; + } + clearInputBuffer(); + insert_sorted_in_ascending_order(list, element); + printf("Элемент успешно добавлен\n"); +} + +void removeElemetFromList(List* list) +{ + int index = 0; + printf("Введите индекс элемента, который хотите удалить: "); + if (scanf("%d", &index) != 1) { + printf("Ошибка: введен некорректный индекс!\n"); + clearInputBuffer(); + return; + } + clearInputBuffer(); + + if (removeElement(list, index)) { + printf("Элемент успешно удален.\n"); + } else { + printf("Что-то пошло не так. Возможно введен неправильный индекс.\n"); + } +} + +void printTheList(List* list) +{ + printf("Список элементов:\n"); + printList(list); +} + +void handleCommands() +{ + printf("Вводите команды. После каждой введенной команды нажимайте Enter\n"); + printf("Чтобы завершить работу с программой, введите 0\n\n"); + List* list = newList(); + int command = 0; + while (1) { + printf("Введите команду: "); + if (scanf("%d", &command) != 1) { + printf("Ошибка: пожалуйста, введите число от 0 до 3!\n"); + clearInputBuffer(); + continue; // Пропускаем остаток цикла и начинаем заново + } + clearInputBuffer(); + if (command == 0) { + break; + } + switch (command) { + case 1: + addElementInList(list); + break; + case 2: + removeElemetFromList(list); + break; + case 3: + printTheList(list); + break; + default: + printf("Вероятно, такой команды не существует\n"); + } + } + deleteList(list); + printf("Работа с программой завершена. Память очищена\n"); +} + +int main() +{ + printMenu(); + handleCommands(); + return 0; +}