Skip to content

Conversation

@IljarSmirnov
Copy link

No description provided.

@IljarSmirnov IljarSmirnov changed the title add lab Смирнов Илья Apr 29, 2024
@IljarSmirnov
Copy link
Author

@KorotinEgor, @kermanglobe, хоть с CMake и проблемы, но сам код можете проверять

Copy link

@kermanglobe kermanglobe left a comment

Choose a reason for hiding this comment

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

если мне не изменяет память, то должна ещё быть упорядоченная таблица на массиве

Comment on lines 25 to 30
std::vector<Node*> memorysearch(std::string name);
int balance(Node* nd);
void smallleftrot(Node* xparent, Node* x);
void smallrightrot(Node* xparent, Node* x);
void bigleftrot(Node* xparent, Node* x);
void bigrightrot(Node* xparent, Node* x);

Choose a reason for hiding this comment

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

я бы эти методы в private поместил

Comment on lines +32 to +33
void clear(std::string name);
polynoms Arithmetic(std::string strexpr);

Choose a reason for hiding this comment

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

в чём резон помещать метод для вычисления выражений внутрь таблиц?

Comment on lines 23 to 24
~AVLTreeTable();
polynoms search(std::string name);

Choose a reason for hiding this comment

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

ключ-строку нужно передавать как const std::string& (иначе каждый раз при вызове функции будет происходить копирование)

Comment on lines 91 to 97
}
polynoms entered(entmon);
table.add(name, entered);
cout << "UnorderedTable: add. Operations: " << counttable << endl;
tree.add(name, entered);
cout << "AVLTreeTable: add. Operations: " << counttree << endl;
hashtable.add(name, entered);

Choose a reason for hiding this comment

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

если я правильно понял, то пользователь должен выбирать, в какую из таблиц он хочет положить полином

Copy link
Author

Choose a reason for hiding this comment

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

В задании написано "Работа происходит сразу с таблицами всех типов.", как я и сделал

Comment on lines 4 to 5
file(GLOB hdrs "*.h*" "../include/*.h")
file(GLOB srcs "*.cpp")

Choose a reason for hiding this comment

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

зачем убрал "../src/*.cpp" ?

Copy link
Author

Choose a reason for hiding this comment

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

Да что с ним, что без него - не работает =)

Comment on lines 4 to 5

static int counttree = 0;

Choose a reason for hiding this comment

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

так counttree работать не будет, ты либо прописываешь эту переменную в хедере как extern int counttree и в исходниках пишешь int counttree, либо помещаешь внутрь класса
при текущей реализации программа-сэмпл выводит 0 операций при вставке, поиске и удалении (что, очевидно, не так)

Comment on lines +224 to +230
}
try {
search(name);
}
catch (std::logic_error& e) {
Node* cur = head;
std::vector<Node*> path = memorysearch(name);

Choose a reason for hiding this comment

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

интересная, конечно, схема с try/catch блоком...
если уж на то пошло, то в catch должно быть const std::exception& e

Copy link
Author

Choose a reason for hiding this comment

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

search выбрасывает logic_error, поэтому и ловится именно он

Comment on lines 56 to 57

polynoms AVLTreeTable::search(std::string name) {

Choose a reason for hiding this comment

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

неплохо бы возвращать не собственно полином, а указатель на cur->data.second
можно будет как минимум сделать проще проверку на наличие элемента в таблице

Comment on lines +21 to +22
if (i >= 1) {
if (s[i] == 'x' && (s[i - 1] == '0' || s[i - 1] == '1' || s[i - 1] == '2' || s[i - 1] == '3' || s[i - 1] == '4' || s[i - 1] == '5' || s[i - 1] == '6' || s[i - 1] == '7' || s[i - 1] == '8' || s[i - 1] == '9')) {

Choose a reason for hiding this comment

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

Suggested change
if (i >= 1) {
if (s[i] == 'x' && (s[i - 1] == '0' || s[i - 1] == '1' || s[i - 1] == '2' || s[i - 1] == '3' || s[i - 1] == '4' || s[i - 1] == '5' || s[i - 1] == '6' || s[i - 1] == '7' || s[i - 1] == '8' || s[i - 1] == '9')) {
if (i >= 1) {
if (s[i] == 'x' && s[i - 1] >= '0' && s[i - 1] <= '9') {

так компактнее будет

Comment on lines 45 to 62
}
TEST(AVLTreeTable, can_clear) {
list<pair<int, double>>a;
a.push_back(make_pair(100, 1));
polynoms A(a);
AVLTreeTable T;
T.add("pol", A);
ASSERT_NO_THROW(T.clear("pol"));
}
TEST(AVLTreeTable, clear_is_correct) {
list<pair<int, double>>a;
a.push_back(make_pair(100, 1));
polynoms A(a);
AVLTreeTable T;
T.add("pol", A);
T.clear("pol");
ASSERT_ANY_THROW(T.search("pol"));
}

Choose a reason for hiding this comment

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

можно добавить тесты на удаление с различными сценариями (удаление листа, вершины с одним или двумя потомками, головы с потомками или без потомков)

Copy link

@KorotinEgor KorotinEgor left a comment

Choose a reason for hiding this comment

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

Методы с арифметикой я не проверял, скажем, что они правильные изначально, а если это не так, то виноват госопдин проверяющий.


class UnorderedTable {
std::vector<std::pair<std::string, polynoms>> table;
size_t size;

Choose a reason for hiding this comment

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

А в чём вообще смысл этой переменной? Ты хранишь размер, чтобы, если что, выдать количество элементов пользователю за О(1), но с данной функцией прекрасно спровляется return table.size()

this->add(rec.first, rec.second);
}
}
void UnorderedTable::add(std::string name, polynoms pol) {
Copy link

@KorotinEgor KorotinEgor Apr 30, 2024

Choose a reason for hiding this comment

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

В некоторых методах деревьев вроде бы поправил, а тут - нет. Лучше передавать что строку, что полином по ссылке, чтобы не копировать одно и то же по 10 раз
В хэшах и тех методах деревьев, что не попали под "некоторые" аналогично

polynoms search(std::string name);
void add(std::string name, polynoms pol);
void clear(std::string name);
void resize();

Choose a reason for hiding this comment

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

А разве не логичнее будет засунуть resize в private? А так, это нарушение принципов ООП

Comment on lines +11 to +16
int res, strsum = 0;
for (int i = 0; i < name.size(); i++) {
strsum += int(name[i]);
}
res = strsum % size;
return res;

Choose a reason for hiding this comment

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

А зачем res вообще существует?, то же можно сказать и про Hash2.

Comment on lines 109 to 112
if (table[(Hash1(name) + i * Hash2(name)) % size] != nullptr) {
if (table[(Hash1(name) + i * Hash2(name)) % size]->state == 0 || table[(Hash1(name) + i * Hash2(name)) % size]->state == -1) {
table[(Hash1(name) + i * Hash2(name)) % size] = new Rec(name, pol);
return;

Choose a reason for hiding this comment

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

Утечка памяти, если элемент явяется удалённым ты просто присваиваешь в Table[...] новый указатель, в то время как старый элемент, на который там раньше был указатель остаётся где-то непонятно где, но точно не удаляется.

Comment on lines +232 to +252
while (true) {
counttree++;
if (name < cur->data.first) {
if (cur->left) {
cur->h += 1;
cur = cur->left;
}
else {
break;
}
}
else {
if (cur->right) {
cur->h += 1;
cur = cur->right;
}
else {
break;
}
}
}

Choose a reason for hiding this comment

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

Не понял смысл этого действия, разве нельзя просто пройтись по path и всем там h++ сделать?

Comment on lines +295 to +318
else {

if (balance(path[i]) == 2) {
if (balance(path[i]->left) >= 0) {
if (i == 0) smallrightrot(nullptr, path[i]);
else smallrightrot(path[i - 1], path[i]);
}
else if (balance(path[i]->left) < 0) {
if (i == 0) bigrightrot(nullptr, path[i]);
else bigrightrot(path[i - 1], path[i]);
}
}
if (balance(path[i]) == -2) {
if (balance(path[i]->right) <= 0) {
if (i == 0) smallleftrot(nullptr, path[i]);
else smallleftrot(path[i - 1], path[i]);
}
else if (balance(path[i]->right) > 0) {
if (i == 0) bigleftrot(nullptr, path[i]);
else bigleftrot(path[i - 1], path[i]);
}
}
seth(path[i]);

Copy link

@KorotinEgor KorotinEgor May 1, 2024

Choose a reason for hiding this comment

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

Эта часть бесполезна, как и весь этот огромный if, его единтсенное теоретичсекое предназначение - чтоб не залесть, куда не надо, но в твоём случае, это опбеспечивает метод balance (в него уже встроена проверка на то, являются ли 1 или 2 потомка нулевыми или нет)

Comment on lines 26 to 29
void smallleftrot(Node* xparent, Node* x);
void smallrightrot(Node* xparent, Node* x);
void bigleftrot(Node* xparent, Node* x);
void bigrightrot(Node* xparent, Node* x);

Choose a reason for hiding this comment

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

повороты должны быть в private, тк они могут изменить дерево так, что оно перестанет быть AVL-деревом или, могут уронить программу(при попытке прочитать не принадлежащую им память), чего ты, как разработчик классов на C++, допускать не должен.

Comment on lines +376 to +379
else if (minval->left != nullptr && minval->right == nullptr) {
path[path.size() - 2]->right == minval->left;
counttree++;
}
Copy link

@KorotinEgor KorotinEgor May 1, 2024

Choose a reason for hiding this comment

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

опять бесполезная часть, после цикла while у cur никогда нет потомков слева, т.е. minnval->left=nullptr всегда

Comment on lines 383 to 391
else {
counttree++;
if (path[path.size() - 2]->left == cur) {
path[path.size() - 2]->left = cur->left;
}
else {
path[path.size() - 2]->right = cur->left;
}
}

Choose a reason for hiding this comment

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

Не рассмтариваешь случай, когда у тебя дерево это голова с 1м левым потомком и ты хочешь удалить голову. Тогда path.size()=1, path[path.size() - 1]->h!=0, cur->right==nullptr, ты попадаешь в это место и деалешь path[path.size() - 2]

Copy link

@KorotinEgor KorotinEgor May 1, 2024

Choose a reason for hiding this comment

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

Кроме того, если ты попал сюда, то ты даже не удаляешь cur, а просто исключешь его из дерева, т.е. ещё одна утечка памяти

@IljarSmirnov
Copy link
Author

@ValentinV95, Здравствуйте, код готов к проверке

Copy link
Owner

@ValentinV95 ValentinV95 left a comment

Choose a reason for hiding this comment

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

Лабораторная принята, часть справидливых замечаний от одногруппников осталась не исправленной и не прокомментирована

@ValentinV95 ValentinV95 added the good first issue Good for newcomers label May 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

good first issue Good for newcomers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants