Einfachverkettete Liste von Swift in Objective-C - Hilfe

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

Aufgrund der Corona-Krise: Die Veröffentlichung von Stellenangeboten und -gesuchen ist bis 31.12.2020 kostenfrei. Das beinhaltet auch Angebote und Gesuche von und für Freischaffende und Selbstständige.

  • Einfachverkettete Liste von Swift in Objective-C - Hilfe

    Hallo,
    ich habe bereits in Swift ein einfachverkettet Liste erstellt.

    Quellcode

    1. import Foundation
    2. // die Klasse für die Listenelemente
    3. class Liste {
    4. var daten = ""
    5. // die Referenz auf das nächste Element
    6. var naechster: Liste?
    7. // die Daten für ein Element setzen
    8. // die Zeichenkette wird übergeben
    9. func setDaten(datenNeu: String) {
    10. // die Zeichenkette setzen
    11. daten = datenNeu
    12. // das Ende markieren
    13. naechster = nil
    14. }
    15. // ein neues Element am Ende der Liste anhängen
    16. // die Zeichenkette wird übergeben
    17. func anhaengen(datenNeu: String) -> Liste {
    18. naechster = Liste()
    19. naechster!.setDaten(datenNeu: datenNeu)
    20. return naechster!
    21. }
    22. // die Ausgabe der kompletten Liste
    23. func ausgeben() {
    24. print(daten)
    25. if naechster != nil {
    26. naechster!.ausgeben()
    27. }
    28. }
    29. }
    30. // ein neues Listenelement erzeugen
    31. var listenAnfang = Liste()
    32. // für das Listenende
    33. var listenEnde = listenAnfang
    34. // die Daten im ersten Listenelement setzen
    35. listenAnfang.setDaten(datenNeu: "Element 1")
    36. // weitere Elemente in einer Schleife anfügen
    37. var element = 2
    38. for element in 2 ..< 10 {
    39. listenEnde = listenEnde.anhaengen(datenNeu: "Element " + String(element))
    40. }
    41. // die Liste ausgeben
    42. listenAnfang.ausgeben()
    Alles anzeigen


    Jetzt soll diese Liste in Objective-C mit der folgende Aufgabenstellung erfolgen:

    1. Erstellen Sie die einfach verkette Liste mit Objekten, die Sie bereits mit Swift erstellt haben, als Objective-C-Terminalprogramm. Neue Elemente sollen dabei immer direkt am Ende der Liste angefügt werden. Das Programm soll also nicht erst nach dem Ende der Liste suchen. Lassen Sie die Liste sowohl vorwärts als auch rückwärts ausgeben. Wie Sie die Ausgaben umsetzen, bleibt Ihnen überlassen. Dokumentieren Sie Ihren Ansatz aber ausführlich.

      Bitte achten Sie bei der Programmierung darauf, dass Sie für die Verbindung der Listenelemente untereinander statt der Referenz einen Zeiger auf die Klasse selbst verwenden müssen. Auch die Klasse NSString erwartet einen Zeiger
    Ich habe bis jetzt folgendes erstellt. Jedoch kann es nicht so ganz richtig sein:

    C-Quellcode: Klasse Listenelement

    1. // Listenelement.h
    2. #import <Foundation/Foundation.h>
    3. @interface Listenelement : NSObject
    4. // die Properties
    5. @property NSString* daten;
    6. @property Listenelement* naechster;
    7. // die Methode zum Setzen der Daten
    8. - (void) datenSetzen: (NSString*) datenNeu;
    9. // die Methode zum Anhängen eines neuen Elements
    10. - (Listenelement*) datenAnhaengen: (NSString*) datenNeu;
    11. // die Methode zur Ausgabe der Liste
    12. - (void) ausgabe;
    13. @end
    Alles anzeigen

    C-Quellcode: Klasse Listenelement

    1. #import "Listenelement.h"
    2. @implementation Listenelement
    3. // die Methode zum Setzen der Daten
    4. - (void) datenSetzen:(NSString *)datenNeu {
    5. // die Zeichenkette setzen
    6. _daten = datenNeu;
    7. // das Ende markieren
    8. _naechster = nil;
    9. NSLog(@"Daten %@", datenNeu);
    10. }
    11. // die Methode zum Anhängen eines neuen Elements
    12. // die Zeichenkette wird übergeben
    13. // die Funktion liefert jetzt auch das Ende zurück
    14. - (Listenelement*) datenAnhaengen:(NSString *)datenNeu {
    15. _naechster = self;
    16. [_naechster datenSetzen: datenNeu];
    17. return _naechster;
    18. }
    19. // Komplette Liste ausgeben
    20. // die Methode ruft sich rekursiv auf, bis das Ende erreicht ist
    21. - (void) ausgabe {
    22. //NSLog(@"%@", _daten);
    23. if (_naechster != nil) {
    24. [_naechster ausgabe];
    25. }
    26. }
    27. @end
    Alles anzeigen

    C-Quellcode: Main Datei

    1. #import <Foundation/Foundation.h>
    2. #import "Listenelement.h"
    3. int main(int argc, const char * argv[]) {
    4. @autoreleasepool {
    5. // Instanz erzeugen
    6. Listenelement *neueListe = [[Listenelement alloc] init];
    7. // Listenende abspeichern
    8. NSString* listenEnde = neueListe;
    9. // die Daten im ersten Listenelement setzen
    10. [neueListe datenSetzen: (@"Element 1")];
    11. // weitere Elemente in einer Schleife anfügen
    12. for (int element = 2; element < 10; element++) {
    13. listenEnde = [neueListe datenAnhaengen:[NSString stringWithFormat:@"Element %d", element]];
    14. }
    15. // die Liste ausgeben
    16. [neueListe ausgabe];
    17. }
    18. return 0;
    19. }
    Alles anzeigen

    Bitte kann mir da einer helfen?!

    Lg Iman
  • Ocean1878 schrieb:


    Bitte achten Sie bei der Programmierung darauf, dass Sie für die Verbindung der Listenelemente untereinander statt der Referenz einen Zeiger auf die Klasse selbst verwenden müssen.
    Häh? Steh‘ ich auf‘m Schlauch? Kann mir jemand erklären, wie das gemeint sein könnte? „Statt der Referenz einen Zeiger...“? Wo soll da der Unterschied sein? Und wieso auf die Klasse und nicht auf eine Instanz, nämlich die des folgenden Objektes?

    Wo hast Du denn diese Aufgabenstellung her?

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • MyMattes schrieb:

    Ocean1878 schrieb:

    Bitte achten Sie bei der Programmierung darauf, dass Sie für die Verbindung der Listenelemente untereinander statt der Referenz einen Zeiger auf die Klasse selbst verwenden müssen.
    Häh? Steh‘ ich auf‘m Schlauch? Kann mir jemand erklären, wie das gemeint sein könnte? „Statt der Referenz einen Zeiger...“? Wo soll da der Unterschied sein? Und wieso auf die Klasse und nicht auf eine Instanz, nämlich die des folgenden Objektes?

    Ich denke das soll einfach nur klarstellen, dass in Objective-C Referenzen über Zeiger funktionieren. Damit man nicht auf die Idee kommt sowas zu schreiben:

    Quellcode

    1. NSString einString;
    Der Teil mit der Klasse ist auch nur dumm ausgedrückt. Dahinter vermute einen Hinweis auf die fehlende Typinferenz.



    @Ocean1878 deiner anhängen Methode würde ich entweder ein Listenelement zum anhängen übergeben oder in der Methode ein neues Element erstellen. Momentan erzeugte du nur zu Beginn ein einziges Listenelement.
    Das Herz besitzt Gründe, die die Vernunft nicht kennt.
  • pierredrks schrieb:

    @Ocean1878 deiner anhängen Methode würde ich entweder ein Listenelement zum anhängen übergeben oder in der Methode ein neues Element erstellen. Momentan erzeugte du nur zu Beginn ein einziges Listenelement.
    Das, und Du müsstest an der Stelle NSString* listenEnde = neueListe; eigentlich eine Compiler-Meldung kassieren: Das Ende solltest Du Dir in einem Listenelement speichern ... und neueListe ist ja eine Instanz dieser Klasse und kein NSString.

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Ocean1878 schrieb:

    Wie sollte dann der Code dann aussehen?
    Na, Du wirst ja wohl kaum erwarten, dass hier jemand Deine Studienaufgabe löst, oder ;)

    Der Hinweis von @pierredrks sollte Dich doch schon einen Riesenschritt nach vorne bringen: Du hast eine Methode datenAnhaengen in Listenelement, die einfach nur eine Eigenschaft des aktuellen Elementes setzt. Stattdessen sollte sie eine neue Instanz von Listenelement erzeugen, deren Daten setzen und sie als Nachfolger im aktuellen Element hinterlegen.

    Dann noch Deine Schleife in main so überarbeiten, dass sie immer an das letzte Element anhängt und nicht an den (unveränderten) Listenanfang...

    Gehe mal Deinen eigenen Code mit Papier und Bleistift durch („Eisenbahn spielen“), dann wirst Du schnell feststellen, wo es hakt.

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von MyMattes ()

  • Ocean1878 schrieb:

    Diese ILS-Fernstudium macht mich wahnsinnig. Denn einige Aufgabenstellungen verstehe ich einfach nicht.
    Ohne Dich jetzt frustrieren zu wollen: ILS-Studierende sind hier schon ein paar Mal mit sehr grundlegenden Verständnisfragen „aufgefallen“. Solltest Du Dich noch in der Probezeit befinden, würde ich mir überlegen, die Zeit / das Geld in ein autodidaktisches Lernen zu investieren ... es sei denn, Du versprichst Dir von besagtem Zertifikat ernsthafte Vorteile.

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Keine Sorge man frustriert mich damit nicht.
    Leider bin ich aus der Probezeit raus, so dass ich das hier durchziehen muss und möchte.
    Jedoch ist es anstrengend ohne autodidaktisches Lernen vorwärts zu kommen.

    Ich mache beruflich komplett was anderes. Jedoch interessiere ich mich für Computern und sehe eventuell eine Möglichkeit mein Berufszweig zu verändern.

    Ich habe auch mit Swift angefangen und es wird auch mit Swift weitergemacht. Jedoch wird Objective-C kurz behandelt. Das ist ebenfalls anstrengend mit nur einem Studienheft, Objective-C zu lernen und umzusetzen.

    Nein, ich habe nicht erwartet, dass man mir die Hausaufgaben macht bzw. die Prüfung schreibt. Deshalb habe ich auch bereits erstellten Code hier eingefügt.

    Eure Tips sind auch sehr wertvoll. Aber für ein Anfänger, der mit dem Sprachgebrauch und Umgang mit Programmiersprachen nichts zutun hatte und "Swift" die erste Sprache ist, kann man nichts großartig anfangen. Im groben verstehe ich ja was ihr meint, aber bei der Umsetzung hackt es.
    Ich bin auch kein theoretischer Mensch. Ich muss es in der Praxis lernen. Daher war die frage, wie man das was ihr meint in Objective-C schreibt.

    Wenn ich auch so lange wie ihr programmieren würde oder es beruflich machen würde, würde ich jedes Wort verstehen und auch umsetzen können. Ich bin also kein Freund davon sich Codes zu kopieren. Jedoch würde ich gerne mal so ein Code sehen, wie man es umsetzt.

    Wenn ich jetzt hier nur die Aufgabenstellung gestellt hätte und gefragt hätte, kann mir einer ein Code dazu schreiben, würde ich es verstehen.

    Lg
  • Ocean1878 schrieb:

    Wenn ich jetzt hier nur die Aufgabenstellung gestellt hätte und gefragt hätte, kann mir einer ein Code dazu schreiben, würde ich es verstehen.
    Vielleicht baue ich gleich mal etwas ausgehend von Deinem Code ... aber Du beziehst Dich jetzt nur auf Deine Situation - danke dafür - und rechtfertigst Dich. Hast Du Dir denn die Hinweise von @pierredrks und mir näher angeschaut und versucht, umzusetzen?

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • MyMattes schrieb:

    Vielleicht baue ich gleich mal etwas ausgehend von Deinem Code
    So, fertig. Es waren wirklich nur die beiden oben genannten Anpassungen notwendig:
    1. In der Methode datenAnhaegen auch wirklich Daten anhängen. Mit anderen Worten ein neues Listenelement erzeugen, dessen Eigenschaften setzen und es vom vormals letzten Element referenzieren. Dann das neue Element zurückgeben.
    2. Beim Erstellen der Liste in der Schleife auch die Referenz auf das letzte Element nutzen, um ein neues anzuhängen.
    In Code sieht es dann so aus (ich würde es anders schreiben / formatieren, wollte aber möglichst nah an Deinem Original bleiben):

    C-Quellcode: Listenelement.m

    1. #import "Listenelement.h"
    2. @implementation Listenelement
    3. // die Methode zum Setzen der Daten
    4. - (void) datenSetzen:(NSString *)datenNeu {
    5. // die Zeichenkette setzen
    6. self.daten = datenNeu;
    7. // das Ende markieren
    8. self.naechster = nil;
    9. NSLog(@"Daten setzen: %@", datenNeu);
    10. }
    11. // die Methode zum Anhängen eines neuen Elements
    12. // die Zeichenkette wird übergeben
    13. // die Funktion liefert jetzt auch das Ende zurück
    14. - (Listenelement*) datenAnhaengen:(NSString *)datenNeu {
    15. Listenelement *neuesElement = [[Listenelement alloc] init];
    16. [neuesElement datenSetzen: datenNeu];
    17. self.naechster = neuesElement;
    18. return neuesElement;
    19. }
    20. // Komplette Liste ausgeben
    21. // die Methode ruft sich rekursiv auf, bis das Ende erreicht ist
    22. - (void) ausgabe {
    23. NSLog(@"Ausgabe: %@", self.daten);
    24. if (self.naechster != nil) {
    25. [self.naechster ausgabe];
    26. }
    27. }
    28. @end
    Alles anzeigen

    C-Quellcode: main.m

    1. #import <Foundation/Foundation.h>
    2. #import "Listenelement.h"
    3. int main(int argc, const char * argv[]) {
    4. @autoreleasepool {
    5. // Instanz erzeugen
    6. Listenelement *neueListe = [[Listenelement alloc] init];
    7. // Listenende abspeichern
    8. Listenelement *listenEnde = neueListe;
    9. // die Daten im ersten Listenelement setzen
    10. [neueListe datenSetzen: (@"Element 1")];
    11. // weitere Elemente in einer Schleife anfügen
    12. for (int element = 2; element < 10; element++) {
    13. listenEnde = [listenEnde datenAnhaengen:[NSString stringWithFormat:@"Element %d", element]];
    14. }
    15. // die Liste ausgeben
    16. [neueListe ausgabe];
    17. }
    18. return 0;
    19. }
    Alles anzeigen
    Die Ausgabe sieht dann erwartungsgemäß so aus:

    Quellcode

    1. 2020-03-14 14:14:04.154762+0100 LinkedList[11731:11934080] Daten setzen: Element 1
    2. 2020-03-14 14:14:04.155516+0100 LinkedList[11731:11934080] Daten setzen: Element 2
    3. 2020-03-14 14:14:04.155605+0100 LinkedList[11731:11934080] Daten setzen: Element 3
    4. 2020-03-14 14:14:04.155763+0100 LinkedList[11731:11934080] Daten setzen: Element 4
    5. 2020-03-14 14:14:04.155823+0100 LinkedList[11731:11934080] Daten setzen: Element 5
    6. 2020-03-14 14:14:04.155874+0100 LinkedList[11731:11934080] Daten setzen: Element 6
    7. 2020-03-14 14:14:04.155919+0100 LinkedList[11731:11934080] Daten setzen: Element 7
    8. 2020-03-14 14:14:04.155965+0100 LinkedList[11731:11934080] Daten setzen: Element 8
    9. 2020-03-14 14:14:04.156009+0100 LinkedList[11731:11934080] Daten setzen: Element 9
    10. 2020-03-14 14:14:04.156060+0100 LinkedList[11731:11934080] Ausgabe: Element 1
    11. 2020-03-14 14:14:04.156102+0100 LinkedList[11731:11934080] Ausgabe: Element 2
    12. 2020-03-14 14:14:04.156141+0100 LinkedList[11731:11934080] Ausgabe: Element 3
    13. 2020-03-14 14:14:04.156180+0100 LinkedList[11731:11934080] Ausgabe: Element 4
    14. 2020-03-14 14:14:04.156215+0100 LinkedList[11731:11934080] Ausgabe: Element 5
    15. 2020-03-14 14:14:04.156252+0100 LinkedList[11731:11934080] Ausgabe: Element 6
    16. 2020-03-14 14:14:04.162696+0100 LinkedList[11731:11934080] Ausgabe: Element 7
    17. 2020-03-14 14:14:04.162809+0100 LinkedList[11731:11934080] Ausgabe: Element 8
    18. 2020-03-14 14:14:04.163007+0100 LinkedList[11731:11934080] Ausgabe: Element 9
    19. Program ended with exit code: 0
    Alles anzeigen
    Das sollte Dir nun weiterhelfen und Respekt: Du bist - glaube ich - der erste, der es geschafft hat, von mir eine Anwort mit komplettem Code zu bekommen ... ich bin eigentlich ein überzeugter Verfechter der "Hilfe zur Selbsthilfe" :D Ich hoffe, Du beherzigst die Ratschläge, bei der Programmentwicklung mehr Zeit in das Konzept und z. B. Pseudo-Code / Diagramme zu stecken und erst dann zur Tastatur zu greifen. Glaube mir, der scheinbare Mehraufwand rechnet sich x-fach.

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Ich danke dir.

    Vor allem, werde ich nächste Woche Operiert und weiß nicht, ob ich mein Beruf noch ausüben kann.
    Deshalb nehme ich das hier ernst.

    Hast du ein Tip für mich wo ich da mit den Diagrammen besser lernen kann. Denn das wird nicht beigebracht.

    Andere Frage: Wofür benötigt man eigentlich diese Verkettete Listen? Wird das wirklich so oft gebraucht?
  • Ocean1878 schrieb:

    Hast du ein Tip für mich wo ich da mit den Diagrammen besser lernen kann.
    Ich meinte jetzt gar keine speziellen Diagramme zur Software-Entwicklung, da gibt es x für die unterschiedlichen Fragestellungen: ERD, Prozessablaufplan, HIPO, ... Mir hilft es viel, ein Problem zu visualisieren: Also auf einem Papier mal 2-3 Kästen malen, das sind die Listenelemente, dann in jedem ein Kästchen als Daten, ein weiteres als Adresse des Nachfolger, letzteres hat dann einen Pfeil auf das nächste Listenelement.

    Mit so einer Skizze kannst Du Dir schnell überlegen, was z. B. beim Anfügen eines Elementes geschehen muss. Oder beim Entfernen, Umordnen, Umkehren... Ich nutzte derartige Darstellungen gerne, um meinen Code bei Problemen theoretisch durchzuspielen. Dabei wäre Dir aufgefallen, dass Du z. B. gar keine neuen Elemente erzeugst.

    Ocean1878 schrieb:

    Andere Frage: Wofür benötigt man eigentlich diese Verkettete Listen? Wird das wirklich so oft gebraucht?
    Geht so. Dadurch, dass verkettete Listen sehr effizientes Hinzufügen und Löschen unterstützen, bilden sie häufig die Grundlage für andere Datenstrukturen wie Stacks oder Queues. Ich muss gestehen, eine solche Liste noch nie für eigene Zwecke implementiert zu haben ... aber sie war schon vor >30 Jahren eine beliebte Programmieraufgabe :)

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.