Przekazywanie zawartości struktury do innej struktury.

0

Główny problem polega na tym, że nie wiem w jaki sposób sprawić, żeby dwie struktury mogły się ze sobą komunikować.

Posiadam strukturę główną (lista jednokierunkowa) wypełnioną danymi name, age, i chciałbym przekopiować wszystkie name do struktury docelowej (również listy jednokierunkowej).

Jak poprawnie napisać taką funkcję CopyMainToTarget? Próbowałem:

#include <iostream>
#include <string>

struct MainStruct { // struktura główna
    MainStruct *next;
    std::string name; 
    int age;
};
struct TargetStruct { // struktura docelowa
    TargetStruct *next;
    std::string name; // wartości name powinny być te same co w MainStruct,
                           // ale zaalokowane w osobnych komórkach pamięci
};

// dodaje do struktury glownej
void AddToMain(MainStruct *&head, const std::string &name, const int &age)
{
    head = new MainStruct {head, name, age};
}

// tutaj mam problem
void CopyMainToTarget(TargetStruct *&head)
{
    head = new TargetStruct {head, head->name};
}

int main()
{
    MainStruct *main_ptr = nullptr;
    AddToMain(main_ptr, "Zosia", 24);
    AddToMain(main_ptr, "Karol", 33);
    AddToMain(main_ptr, "Marek", 25);
    // do tej pory wszystko dziala

    TargetStruct *target_ptr = nullptr;
    CopyMainToTarget(target_ptr);
}

Ten kod nie ma sensu, ale jest to jedyny który się skompilował. : D Nie widzę w jaki sposób funkcja CopyMainToTarget miałaby się komunikować z MainStruct.

Próbowałem również:

void CopyMainToTarget(MainStruct *&head)
{
    head = new TargetStruct {head, head->name};
}

i inne kombinacje, ale wywala przeróżne złożone błędy.

Dla mnie to czarna magia, a myślę że rozwiązanie jest proste. Jak przekopiować dane z MainStruct do TargetStruct? Jak przekazywać poprawnie strukturę do funkcji? Jak zrobić aby obie struktury mogły się w funkcji komunikować?

0

Użyj std::x gdzie x to vector/deque/list/forward_list w tej kolejności preferencji zamiast wymyślać koło na nowo. Wtedy zwykłe std::transform pozwoli na takie przypisanie.

No i na dodatek: https://dsp.krzaq.cc/post/176/ucze-sie-cxx-kiedy-uzywac-new-i-delete/

0

Żeby wykonać kopie czegoś to trzeba przede wszystkim to coś mieć.

// Co ta funkcja ma kopiować? Gdzie jest źródło danych? 
void CopyMainToTarget(TargetStruct *&head)
{
    head = new TargetStruct {head, head->name};
}
1

Podałem Ci wzór, Stosuj go.

void copyLists(node * head, node * head2) {
	node * tmp = head;
	while (tmp) {
		head2->data = tmp->data; // może jeszcze inne pola
		tmp = tmp->nextptr;
		head2 = head2->nextptr;
	}
}

Poza tym, żeby skopiować coś do listy docelowej, musi być w niej miejsce! Czyli Musisz ją zainicjalizować i utworzyć tyle pól, żeby pomieścić zawartość listy kopiowanej.
Ten pattern jest absolutnie podstawowy, Stosujesz go również do kontenerów STL:

void do_sth2(I first, I last) { // I = Iterator type
	while (firs != last) {
		/* do stuff with *first */
		++first;
	}
}

W przypadku kopiowania, Musisz, przed wywołaniem funkcji mieć pewność, że obie listy mają tę samą długość.
Ogólnie w przypadku takich algorytmów, że wysyłasz tylko iterator do początku (jak, np. do_sth - z poprzedniego postu), warunkiem wstępnym, ich poprawnego działania jest to, że inkrementowanie iteratora nie wyrzuci go z jego zasięgu. Aby to zapewnić, Muisz podać odpowiedni predykat, tutaj: while (tmp) - zrobi robotę. Gdyż jest to, tak naprawdę, zapytanie: czy tmp wskazuje już na koniec? W sensie, oczywiście przedziału ("range") półotwartego, [begin, end), (jako, że takie sa najbardziej interesujące z puntu widzenia informatyki), czyli end wskazuje na pierwszy element za końcem - "granicę" (w sensie matematycznym).

0

Rozwiązane za pomocą:

void CopyMainToTarget(MainStruct *pHeadMain, TargetStruct *&pHeadTarget)
{
    while (pHeadMain)
    {
        pHeadTarget = new TargetStruct {pHeadTarget, pHeadMain->name};
        pHeadMain = pHeadMain->pNextMain;
    }
}

Wada tego rozwiązania to to, że dla listy MainStruct: Zosia, Kasia, Basia lista TargetStruct będzie miała elementy w odwrotnej kolejności tj. Basia, Kasia, Zosia. Ale taki już chyba urok list jednokierunkowych.

Wydajniejsze powinno być odwrócenie listy czy od razu wkładania zamiast na początek to na koniec listy (iteracyjnie czy rekurencyjnie lepiej?).

1 użytkowników online, w tym zalogowanych: 0, gości: 1