#c
#c
Вопрос:
Изучаю C с помощью Bjarne Stroustrup PPP2 и застрял в упражнении 11 из 17 главы.Там я должен понять, Link* add(Link* n)
функция, где помещается объект после, как я могу догадаться, что это то же самое, что Link* insert(Link* n)
функция, где помещается объект раньше.Проблема в том, что моя функция добавления не работает должным образом, например, вызывает this*
указатель, а prev
указатель не назначен должным образом. Мой источник —>>
#include <iostream>
#include <vector>
#include <sstream>
#include <string>
using namespace std;
class Link {
public:
Link(string n, Link* p = nullptr, Link* s = nullptr) :value{n}, prev{ p }, succ{ s }{};
string value;
Link* insert(Link* n);
Link* add(Link* n);
Link* erase();
Link* find(const stringamp; s);
const Link* find(const stringamp; s) const;
Link* advance(int n);
Link* next() const { return succ;}
Link* previous() const { return prev; }
private:
Link* prev;
Link* succ;
};
Link* Link::insert(Link* n) {
if (n == nullptr) return this;
if (this == nullptr) return n;
n->succ = this;
if (prev) prev->succ = n;
n->prev = prev;
prev = n;
return n;
}
Link* Link::add(Link* n) {
if (n == nullptr) return this;
if (this == nullptr) return n;
n->prev = this;
if(succ) succ->prev = n;
n->succ = succ;
succ = n;
return n;
}
Link* Link::erase() {
if (this == nullptr) return nullptr;
if (succ) succ->prev = prev;
if (prev) prev->succ = succ;
return succ;
}
Link* Link::find(const stringamp; s) {
Link* p=this;
while (p) {
if (p->value == s) return p;
p = next();
}
return nullptr;
}
const Link* Link::find(const stringamp; s) const {
const Link* p = this;
while (p) {
if (p->value == s) { return p; }
p=p->next();
}
return nullptr;
}
Link* Link::advance(int n) {
Link* p=this;
if (p == nullptr) return nullptr;
if (0 < n) {
while (n--) {
if (p->succ == nullptr) return nullptr;
p = p->succ;
}
}
else if (n < 0) {
while (n ) {
if (p->prev == nullptr) return nullptr;
p = p->prev;
}
}
return p;
}
void print_all(Link* p) {
cout << "{ ";
while (p) {
cout << p->value;
if (p = p->next())cout << ", ";
}
cout << " }";
}
int main()
{
Link* norse_gods = new Link{ "Thor"};
norse_gods = norse_gods->insert(new Link{ "Odin"});
norse_gods = norse_gods->insert(new Link{ "Loki"});
norse_gods = norse_gods->insert(new Link{ "Freia" });
Link* greek_gods = new Link{ "Hera" };
greek_gods = greek_gods->add(new Link{ "Appolo" }); //There is Appolo is must be placed before "Hera", but is just eat her =)
greek_gods = greek_gods->insert(new Link{ "Athena"});
greek_gods = greek_gods->insert(new Link{ "Ares"});
greek_gods = greek_gods->insert(new Link{ "Poseidon"});
/*
Link* p = greek_gods->find("Mars");
if (p) p->value="Ares";
Link* p2 = norse_gods->find("Zeus");
if (p2) {
if (p2 == norse_gods) norse_gods = p2->next();
p2->erase();
greek_gods=greek_gods->insert(p2);
}
*/
print_all(norse_gods);
cout << "n";
print_all(greek_gods);
cout << "n";
}
Мой вывод —>
{ Фрейя, Локи, Один, Тор }
{ Посейдон, Арес, Афина, Апполо }
Где создается перед Hera?
Спасибо за внимание, ребята, надеюсь на вашу помощь.
Комментарии:
1.
if (this == nullptr)
0_02. Да, это странно,но этот код взят из книги.
Ответ №1:
Проблема просто в том, что вы не печатаете свой второй список с самого начала, так как greek_gods
указывает на его второй элемент.
Попробуйте:
print_all(greek_gods->previous());
Если вы не понимаете почему, я предлагаю использовать ручку и бумагу и записывать, как список выглядит после каждого обновления. Или используйте отладчик.
Комментарии:
1. Спасибо. Но с
print_all(greek_gods->previous())
у меня есть этот вывод. Не могу понять, почему поместите Hera на первое место.{ Hera, Poseidon, Ares, Appolo, Athena }
2. @c_thief Потому что после
add
,greek_gods
указывает наApollo
. Затем вы вставляете элементы между ними. Это точно соответствует коду. Опять же, используйте ручку и бумагу и решайте каждую операцию по отдельности.
Ответ №2:
Спасибо. Мне просто нужен был свежий взгляд. Когда вставка работает, просто каждый раз последовательно перемещает предыдущее. После изменения бита add
функция
Link* Link::insert(Link* n) {
if (n == nullptr) return this;
if (this == nullptr) return n;
if (prev) {
n->succ = prev;
prev->prev = n;
n->prev = prev->prev;
}
else {
n->succ = this;
n->prev = prev;
prev = n;
}
return n;
На данный момент вывод: { Poseidon, Ares, Dionis, Athena, Hera, Appolo }
Спасибо!