#c #binary-search-tree
#c #binary-search-tree
Вопрос:
Я создаю бинарное дерево поиска для бизнеса по прокату фильмов (теоретически). Мне нужно вывести «Фильм не найден», если введено название, которого нет в прокате фильмов. Я не уверен, как это сделать, не получая ошибку сегментации каждый раз. Я не уверен, что еще попробовать — для меня этот код имеет смысл. Я только новичок — пожалуйста, будьте проще со мной. Любая помощь будет принята с благодарностью! (Вы можете найти мою функцию if, которая пытается вывести «Фильм не найден» между тремя косыми чертами (///) ближе к концу моего кода.
void MovieTree::rentMovie(std::string title)
{
MovieNode *foundMovie = root;
//MovieNode *parent = NULL;
if (root == NULL)
{
cout << "Movie not found." << endl;
return;
}
else
{
foundMovie = root;
while (foundMovie != NULL)
{
if (foundMovie == NULL) //tree is empty
{
cout << "Movie not found." << endl;
}
else
{
if (foundMovie->title.compare(title) > 0) //uses ASCII to determine where titles are
{
foundMovie->parent = foundMovie;
foundMovie = foundMovie ->leftChild;
//cout << "printed left" << endl; //debugging
if (foundMovie->title.compare(title) == 0 amp;amp; foundMovie->quantity > 0)
{
foundMovie->quantity--;
cout << "Movie has been rented." << endl;
//Title entered matches title found
cout << "Movie Info:" << endl;
cout << "===========" << endl;
cout << "Ranking:" << foundMovie->ranking << endl;
cout << "Title:" << foundMovie->title << endl;
cout << "Year:" << foundMovie->year << endl;
cout << "Quantity:" << foundMovie->quantity << endl;
break;
}
else if (foundMovie->quantity ==0)
{
//If movie is out of stock
cout << "Movie out of stock." << endl;
break;
}
}
else //check rightChild
{
foundMovie->parent = foundMovie;
foundMovie = foundMovie->rightChild;
//cout << "printed right" << endl; //debugging
if (foundMovie->title.compare(title) == 0 amp;amp; foundMovie->quantity > 0) //title entered matches title found
{
foundMovie->quantity--;
cout << "Movie has been rented." << endl;
cout << "Movie Info:" << endl;
cout << "===========" << endl;
cout << "Ranking:" << foundMovie->ranking << endl;
cout << "Title:" << foundMovie->title << endl;
cout << "Year:" << foundMovie->year << endl;
cout << "Quantity:" << foundMovie->quantity << endl;
break;
}
else if (foundMovie->quantity ==0)
{
//movie is found but out of stock
cout << "Movie out of stock." << endl;
break;
}
}
}
}
///
if (foundMovie->title == title)
{
cout << "found the movie" << endl;
}
else
{
cout << "Movie not found." << endl;
}
///
}
}
Комментарии:
1. ericlippert.com/2014/03/05/how-to-debug-small-programs
2.
foundMovie->parent = foundMovie;
это не очень хорошая идея; это создает циклическую зависимость.3. Еще одна рекомендация: отделите логику фильма от логики дерева. Это позволяет вам отдельно протестировать дерево и фильм и легко определить, в чем ошибка. Одновременное тестирование обоих ставит вас в неприятное положение, когда вы можете фактически исправить ошибку в одном и не осознавать этого из-за ошибки в другом.
4. Поскольку вы указали, что вы новичок, вот пошаговый рефакторинг вашего кода: pastebin.com/4tP5VzKK
Ответ №1:
Некоторые замечания / ошибки в вашем коде
-
Вы не можете удалить больше полезных условий: это снижает читаемость вашего кода.
while (foundMovie != NULL) { if (foundMovie == NULL) // false by construction!!! ... }
-
foundMovie->parent = foundMovie;
должно исчезнуть. Это создает циклическую зависимость! -
Ваш последний оператор
if (foundMovie->title == title)
может создать ошибку сегментации, посколькуfoundMovie
в этот момент может быть NULL.
Вот возможное переписывание:
void MovieTree::rentMovie(std::string title)
{
MovieNode *foundMovie = root;
if (root == NULL)
{
cout << "Movie not found." << endl;
return;
}
foundMovie = root;
while (foundMovie != NULL)
{
int compareTitle = foundMovie->title.compare(title); //uses ASCII to determine where titles are
if (compareTitle > 0)
{
foundMovie = foundMovie ->leftChild;
}
else if (compareTitle < 0) //check rightChild
{
foundMovie = foundMovie->rightChild;
}
else { // compareTitle == 0
if (foundMovie->quantity > 0)
{
foundMovie->quantity--;
cout << "Movie has been rented." << endl;
//Title entered matches title found
cout << "Movie Info:" << endl;
cout << "===========" << endl;
cout << "Ranking:" << foundMovie->ranking << endl;
cout << "Title:" << foundMovie->title << endl;
cout << "Year:" << foundMovie->year << endl;
cout << "Quantity:" << foundMovie->quantity << endl;
break;
}
else if (foundMovie->quantity ==0)
{
//If movie is out of stock
cout << "Movie out of stock." << endl;
break;
}
}
}
// be sure that foundMovie->title == title is equivalent to foundMovie->title.compare(title) == 0
if (foundMovie amp;amp; foundMovie->title == title)
{
cout << "found the movie" << endl;
}
else
{
cout << "Movie not found." << endl;
}
}
Комментарии:
1. Большое вам спасибо. Я не был уверен, как еще это сделать — я ценю ваше мнение.