Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions semester_1/homework7/binarySearchTree/String/String.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "String.h"

char *getString(size_t * const len, FILE * filename, char const endOfLine)
{
*len = 0;
size_t capacity = 1;
char *s = (char *)malloc(sizeof(char));
if (s == NULL)
{
return NULL;
}

for (char c = fgetc(filename); c != endOfLine && c != EOF; c = fgetc(filename))
{
s[(*len)++] = c;

if (*len >= capacity)
{
capacity *= 2;
s = (char *)realloc(s, capacity * sizeof(char));
if (s == NULL)
{
return NULL;
}
}
}

s[*len] = '\0';

return s;
}

char *copyString(char * const string)
{
const size_t len = strlen(string);
char *copy = (char *)malloc(len * sizeof(char));
if (copy != NULL)
{
strcpy(copy, string);
}
return copy;
}
8 changes: 8 additions & 0 deletions semester_1/homework7/binarySearchTree/String/String.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#pragma once

#include <stdbool.h>
#include <string.h>
#include <stdio.h>

char *getString(size_t * const len, FILE * filename, char const endOfLine);
char *copyString(char * const string);
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "binarySearchTree.h"
#include "../String/String.h"

typedef struct Node
{
char *value;
int key;
struct Node *leftChild;
struct Node *rightChild;
} Node;

typedef struct Dictionary
{
Node *root;
} Dictionary;

Dictionary *createDictionary(void)
{
return (Dictionary *)calloc(1, sizeof(Dictionary));
}

static Node **searchNode(Node **const root, const int key)
{
if (*root == NULL)
{
return root;
}

if (key == ((*root)->key))
{
return root;
}

if (key < (*root)->key)
{
return searchNode(&((*root)->leftChild), key);
}
return searchNode((&(*root)->rightChild), key);
}

DictionaryErrorCode append(Dictionary * const dictionary, int const key, char * const value, bool const copyRequired)
{
char *valueCopy = value;
if (copyRequired)
{
valueCopy = copyString(value);
if (valueCopy == NULL)
{
return memoryError;
}
}

Node **nodeToWriteTo = searchNode(&(dictionary->root), key);
if (*nodeToWriteTo == NULL)
{
Node *newNode = (Node *)calloc(1, sizeof(Node));
if (newNode == NULL)
{
free(valueCopy);
return memoryError;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

не почистили valueCopy

}
newNode->key = key;
*nodeToWriteTo = newNode;
}
(*nodeToWriteTo)->value = valueCopy;
return ok;
}

static void deleteNode(Node *const nodeToDelete)
{
if (nodeToDelete != NULL)
{
free(nodeToDelete->value);
free(nodeToDelete);
}
}

static Node *getMinNode(Node *const root)
{
Node *currentNode = root;
for (; currentNode->leftChild != NULL; currentNode = currentNode->leftChild)
;
return currentNode;
}

void deleteElement(Dictionary *const dictionary, int const key)
{
Node **nodeToDelete = searchNode(&(dictionary->root), key);
if (*nodeToDelete == NULL)
{
return;
}

Node *left = (*nodeToDelete)->leftChild;
Node *right = (*nodeToDelete)->rightChild;

deleteNode(*nodeToDelete);

if (left != NULL)
{
if (right != NULL)
{
*nodeToDelete = right;
Node *minNode = getMinNode(right);
minNode->leftChild = left;
return;
}
*nodeToDelete = left;
return;
}
else if (right != NULL)
{
*nodeToDelete = right;
return;
}
*nodeToDelete = NULL;
}

static void deleteRecursion(Node *root)
{
if (root == NULL)
{
return;
}
deleteRecursion(root->leftChild);
deleteRecursion(root->rightChild);
deleteNode(root);
}

void deleteDictionary(Dictionary *dictionary)
{
deleteRecursion(dictionary->root);
free(dictionary);
}

char *getValue(Dictionary *const dictionary, const int key)
{
Node **foundNode = searchNode(&(dictionary->root), key);
if (*foundNode == NULL)
{
return NULL;
}
return (*foundNode)->value;
}

bool keyCheck(Dictionary *const dictionary, const int key)
{
return *(searchNode(&(dictionary->root), key)) != NULL;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once
#include <stdbool.h>

typedef struct Dictionary Dictionary;

typedef enum DictionaryErrorCode
{
ok,
memoryError
} DictionaryErrorCode;

Dictionary *createDictionary(void);
char *getValue(Dictionary *const dictionary, const int key);
bool keyCheck(Dictionary *const dictionary, const int key);
DictionaryErrorCode append(Dictionary * const dictionary, int const key, char * value, bool const copyRequired);
void deleteElement(Dictionary * const dictionary, int const key);
void deleteDictionary(Dictionary * const dictionary);
140 changes: 140 additions & 0 deletions semester_1/homework7/binarySearchTree/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>

#include "binarySearchTree/binarySearchTree.h"
#include "String/String.h"
#include "tests/test.h"
#include "userInput.h"

#define PROGRAM_FINISHED_CORRECTLY 0
#define MEMORY_ERROR 1
#define INPUT_ERROR 2
#define TESTS_ARE_NOT_PASSED 3

#define SOMETHING_WENT_WRONG_MESSAGE "Похоже, что то пошло не так\n"

const size_t commandsCount = 5;

static void scanfCheck(int scanned, Dictionary * const dictionary)
{
if (scanned != 1)
{
printf("%s", SOMETHING_WENT_WRONG_MESSAGE);
deleteDictionary(dictionary);
exit(INPUT_ERROR);
}
}

static UserInput userInput(Dictionary * const dictionary)
{
UserInput input = exitCommand;
scanfCheck(scanf("%d", &input), dictionary);

while (input >= commandsCount)
{
printf("Проверьте правильность ввода\n");
scanfCheck(scanf("%d", &input), dictionary);
}

return input;
}

static const UserInput getCommand(Dictionary * const dictionary)
{
printf("\nДоступные команды:\n0 – выйти\n1 – добавить в словарь значение по ключу \n2 – получить из словаря значение по ключу\n3 – проверить наличие заданного ключа в словаре\n4 - удалить заданный ключ и значение по нему");
printf("\nВведите номер, соответствующий команде, которую вы хотите выполнить\n");

UserInput input = userInput(dictionary);

return input;
}

int main(void)
{
setlocale(LC_ALL, "Rus");
if (!test())
{
printf("Простите, но программа сейчас не работает\n");
return TESTS_ARE_NOT_PASSED;
}

Dictionary *dictionary = createDictionary();
if (dictionary == NULL)
{
return MEMORY_ERROR;
}

DictionaryErrorCode dictionaryErrorCode = ok;
size_t len = 0;
UserInput input = checkKeyCommand;
while (input != exitCommand)
{
input = getCommand(dictionary);
switch (input)
{
case appendCommand:
{
printf("Введите ключ: ");
int key = 0;
scanfCheck(scanf("%d", &key), dictionary);
fgetc(stdin);
printf("Введите значение: ");
char *value = getString(&len, stdin, '\n');
if (value == NULL)
{
printf("Недостаточно памяти\n");
deleteDictionary(dictionary);
return MEMORY_ERROR;
}
dictionaryErrorCode = append(dictionary, key, value, false);
break;
}

case getValueCommand:
{
printf("Введите ключ: ");
int key = 0;
scanfCheck(scanf("%d", &key), dictionary);
char * value = getValue(dictionary, key);
if (value == NULL)
{
printf("Такого ключа нет в словаре\n");
break;
}
printf("Значение по ключу %d: %s\n", key, value);
break;
}

case checkKeyCommand:
{
printf("Введите ключ: ");
int key = 0;
scanfCheck(scanf("%d", &key), dictionary);
printf("%s", (keyCheck(dictionary, key) ? "Такой ключ есть в словаре\n" : "В словаре нет такого ключа\n"));
break;
}

case deleteElementCommand:
{
printf("Введите ключ: ");
int key = 0;
scanfCheck(scanf("%d", &key), dictionary);
deleteElement(dictionary, key);
printf("Элемент удален\n");
break;
}

case exitCommand:
{
printf("Завершение работы\n");
deleteDictionary(dictionary);
}

default:
break;
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

явно чистить везде словарь

return PROGRAM_FINISHED_CORRECTLY;
}
Loading