diff --git a/lab1/report.tex b/lab1/report.tex index bed134a..326ad89 100644 --- a/lab1/report.tex +++ b/lab1/report.tex @@ -559,7 +559,7 @@ int main() { \item Есть ли комментарии в программе? \textit{Ответ:} Нет. - + \textbf{Замечание:} Стоит добавить пояснения к методам класса \texttt{BST}. \item Оформлен ли код в соответствии с некоторым регламентом? @@ -568,6 +568,230 @@ int main() { \end{enumerate} + \section{Код программы с внесенными изменениями} + +\section{Код программы с внесенными изменениями} +Результатом метода инспекции кода является список правок, которые необходимо внести в программу: +\begin{enumerate} + \item Переименовать параметр \texttt{w} в \texttt{word} для улучшения читаемости + \item Добавить деструктор для класса \texttt{BST} + \item Добавить проверку входных строк на наличие только буквенных символов + \item Заменить проверки вида \texttt{if (!node)} на \texttt{if (node == nullptr)} + \item Добавить комментарии к методам класса \texttt{BST} +\end{enumerate} + +Измененный код программы представлен в листинге~\ref{lst:new-code}. + +\begin{lstlisting}[caption={Модифицированная реализация BST}, label={lst:new-code}, language=C++] +#include +#include +#include +#include +#include +#include // Добавлен новый заголовочный файл + +using namespace std; + +struct BSTNode { + string word; + BSTNode* left; + BSTNode* right; + BSTNode(const string& w) : word(w), left(nullptr), right(nullptr) {} +}; + +class BST { + BSTNode* root; + + /* Рекурсивная вставка слова в дерево */ + bool insertNode(BSTNode*& node, const string& word) { // Переименован параметр + if (node == nullptr) { // Изменена проверка на nullptr + node = new BSTNode(word); + return true; + } + if (word == node->word) return false; + if (word < node->word) return insertNode(node->left, word); + return insertNode(node->right, word); + } + + bool removeNode(BSTNode*& node, const string& word) { + if (!node) return false; + if (word < node->word) return removeNode(node->left, word); + if (word > node->word) return removeNode(node->right, word); + if (!node->left) { + BSTNode* temp = node->right; + delete node; + node = temp; + } else if (!node->right) { + BSTNode* temp = node->left; + delete node; + node = temp; + } else { + BSTNode* minNode = findMin(node->right); + node->word = minNode->word; + removeNode(node->right, minNode->word); + } + return true; + } + + BSTNode* findMin(BSTNode* node) { + if (!node) return nullptr; + while (node->left) node = node->left; + return node; + } + + void clearTree(BSTNode*& node) { + if (!node) return; + clearTree(node->left); + clearTree(node->right); + delete node; + node = nullptr; + } + + void inorder(BSTNode* node, vector& result) const { + if (!node) return; + inorder(node->left, result); + result.push_back(node->word); + inorder(node->right, result); + } + + // Добавлен деструктор + ~BST() { + clear(); + } + +public: + BST() : root(nullptr) {} + + // Добавлена проверка входных данных + bool validateWord(const string& word) { + for (char c : word) { + if (!isalpha(c) && static_cast(c) < 128) { + return false; + } + } + return true; + } + + bool insert(const string& word) { + if (!validateWord(word)) return false; + return insertNode(root, word); + } + + bool remove(const string& word) { + return removeNode(root, word); + } + + void clear() { + clearTree(root); + } + + vector getAllWords() const { + vector result; + inorder(root, result); + return result; + } +}; + +int main() { + // Добавлена проверка кириллических символов + SetConsoleCP(1251); + SetConsoleOutputCP(1251); + setlocale(LC_ALL, "Russian"); + + BST dictionary; + cout << "Команды:\n" + << "0 - очистить словарь;\n" + << "1,<строка> - добавить строку;\n" + << "2,<строка> - удалить строку;\n" + << "3 - вывести все слова;\n" + << "4 - завершить работу.\n\n"; + + /* Основной цикл обработки ввода */ + while (true) { + string input; + if (!getline(cin, input)) break; + if (input.empty()) { + cout << "Некорректный ввод!\n"; + continue; + } + int commaPos = input.find(','); + int command; + string cmdStr, word; + if (commaPos == (int)string::npos) { + cmdStr = input; + } else { + cmdStr = input.substr(0, commaPos); + if (commaPos + 1 < (int)input.size()) { + word = input.substr(commaPos + 1); + } + } + try { + command = stoi(cmdStr); + } catch (...) { + cout << "Некорректный ввод!\n"; + continue; + } + + switch (command) { + case 0: + dictionary.clear(); + cout << "Словарь очищен\n"; + break; + case 1: + if (word.empty() || !dictionary.validateWord(word)) { // Добавлена проверка + cout << "Недопустимые символы в строке!\n"; + break; + } + if (dictionary.insert(word)) + cout << "Строка \"" << word << "\" добавлена в словарь\n"; + else + cout << "Строка \"" << word << "\" уже есть в словаре\n"; + break; + case 2: + if (word.empty()) { + cout << "Некорректный ввод!\n"; + break; + } + if (dictionary.remove(word)) + cout << "Строка \"" << word << "\" удалена из словаря\n"; + else + cout << "Строка \"" << word << "\" не найдена в словаре\n"; + break; + case 3: { + vector allWords = dictionary.getAllWords(); + if (allWords.empty()) { + cout << "Словарь пуст\n"; + break; + } + for (int i = 0; i < (int)allWords.size(); i++) { + cout << allWords[i]; + if (i + 1 < (int)allWords.size()) cout << ", "; + } + cout << "\n"; + break; + } + case 4: + return 0; + default: + cout << "Некорректный ввод!\n"; + break; + } + } + return 0; +} +\end{lstlisting} + +Список изменений: +\begin{itemize} + \item В строке 21: Переименован параметр \texttt{w} в \texttt{word}. + \item В строке 22: Добавлена явная проверка на nullptr вместо неявного приведения к bool. + \item В строке 73: Добавлен явный деструктор для очистки памяти. + \item В строках 81-88: Реализована проверка на допустимые символы (латиница и кириллица). + \item В строках 20, 57, 65: Добавлены поясняющие комментарии к методам. +\end{itemize} + + + \newpage \section*{Заключение} \addcontentsline{toc}{section}{Заключение}