smoon Geschrieben 15. Mai 2008 Geschrieben 15. Mai 2008 Hallo, Gegeben ist ein Array[0..n-1], welches ganze Zahlen zw. 0 und n enthält. In diesem Array soll jetzt die fehlende Zahl x mit 0<= x <= n in O(n) ermittelt werden. Das schwierige ist jedoch das man nur auf das k-te Bit des i-ten Elements in kostanter Zeit zugreifen kann. Also ein Zugriff nur mittels A[k] zur Verfügung steht. Mein Gedankengang war erstmal, das man überprüft ob eine gerade od. ungerade Zahl fehlt, welches ja anhand des ersten Bits leicht geprüft werden kann. Somit hätte man ja schon die hälfte der Möglichkeiten eliminiert. Jedoch hab ich noch keine Idee, wie ich jetzt weiter verfahren soll. Hoffe mein Anliegen ist verständlich und ihr habt ein paar Ideen dazu Zitieren
Jan Jansen Geschrieben 15. Mai 2008 Geschrieben 15. Mai 2008 Such einen (Nicht-)Gruppenwechsel Gerade/Ungerade Zitieren
smoon Geschrieben 15. Mai 2008 Autor Geschrieben 15. Mai 2008 Hatte vergessen dazu zu schreiben, dass es sich um ein unsortietes Array handelt. Zitieren
Klotzkopp Geschrieben 15. Mai 2008 Geschrieben 15. Mai 2008 Die Gesamtzahl der gesetzten Bits an Stelle k für alle Zahlen von 0 bis n steht fest. Wenn du dein Array nachzählst, und deine Summe für ein bestimmtes Bit um 1 zu klein ist, ist dieses Bit bei der fehlenden Zahl gesetzt. Zitieren
TDM Geschrieben 15. Mai 2008 Geschrieben 15. Mai 2008 Such einen (Nicht-)Gruppenwechsel Gerade/Ungerade 1, 2, 3, 4, 7, 8, 9 Oder fehlt immer nur eine Zahl? Zitieren
smoon Geschrieben 15. Mai 2008 Autor Geschrieben 15. Mai 2008 Die Gesamtzahl der gesetzten Bits an Stelle k für alle Zahlen von 0 bis n steht fest. Wenn du dein Array nachzählst, und deine Summe für ein bestimmtes Bit um 1 zu klein ist, ist dieses Bit bei der fehlenden Zahl gesetzt. Das würde doch bedeuten das ich für jedes Element einmal alle Bits durchgehen muss. Dies würde jedoch einen Aufwand von O(n²) haben, oder hab ich jetzt was falsch verstanden? Zitieren
smoon Geschrieben 15. Mai 2008 Autor Geschrieben 15. Mai 2008 1, 2, 3, 4, 7, 8, 9 Oder fehlt immer nur eine Zahl? Ja es fehlt immer nur eine Zahl. Zitieren
Klotzkopp Geschrieben 15. Mai 2008 Geschrieben 15. Mai 2008 (bearbeitet) Das würde doch bedeuten das ich für jedes Element einmal alle Bits durchgehen muss. Dies würde jedoch einen Aufwand von O(n²) haben, oder hab ich jetzt was falsch verstanden?Der Aufwand wäre O(n log n), aber natürlich hast du damit im Prinzip Recht. Bearbeitet 15. Mai 2008 von Klotzkopp Zitieren
smoon Geschrieben 15. Mai 2008 Autor Geschrieben 15. Mai 2008 Gesucht ist jedoch leider ein Algorithmus, welcher dies in O(n) erledigt Zitieren
Klotzkopp Geschrieben 15. Mai 2008 Geschrieben 15. Mai 2008 Gesucht ist jedoch leider ein Algorithmus, welcher dies in O(n) erledigt Da sehe ich schwarz. Wenn man ganze Zahlen auf einmal verknüpfen könnte, ginge das in O(n), aber man braucht ja schon O(n log n), um überhaupt auf alle Bits zuzugreifen. Oder ist das ein Array eines konkreten integralen Datentyps, d.h. die Anzahl der Bits ist irgendwie beschränkt? Zitieren
smoon Geschrieben 15. Mai 2008 Autor Geschrieben 15. Mai 2008 Ja ich würde annehmen, dass die Bits in Abhängigkeit von n beschränkt sind. Denn ln(n)/ln(2) aufgerundet ergibt ja die Anzahl der Bits die benötigt werden um n als Dualzahl darzustellen. Zitieren
Klotzkopp Geschrieben 15. Mai 2008 Geschrieben 15. Mai 2008 Ja ich würde annehmen, dass die Bits in Abhängigkeit von n beschränkt sind. Denn ln(n)/ln(2) aufgerundet ergibt ja die Anzahl der Bits die benötigt werden um n als Dualzahl darzustellen.Das ist klar. Ich meinte, ob die Anzahl der Bits absolut beschränkt ist, z.B. weil es sich um ein Array eines 32-Bit-Datentyps handelt. Aber das wäre wohl Unsinn, denn dann wäre sowieso alles in O(1) machbar, denn mit der Anzahl der Bits wäre auch n selbst beschränkt. Zitieren
flashpixx Geschrieben 15. Mai 2008 Geschrieben 15. Mai 2008 Hallo, wenn ich das richtig verstehe - bitte korrigiert mich - hab ich ein Element mit n-1 Zahlen aus N. Ich kann doch einfach iterativ durch gehen und summieren, einmal über das Arrayelement und einmal über den Zähler. Der Zähler beginnt bei 0 und endet bei n-1, d.h. die beiden Summen müssten identisch sein, da sie beide bei 0 beginnen. Da es iterativ ist ergibt sich formal doch O(c*n) = O(n) Ich hoffe ich hab das jetzt auf die Schnelle korrekt verstanden Phil Zitieren
smoon Geschrieben 15. Mai 2008 Autor Geschrieben 15. Mai 2008 Um die Werte zu summieren, müsstest man einmal jedes Element durchgehen => O(n) und die einzelnen Bits jedes Elements 0 => O(log n). Das ergibt dann eine Komplexität von O(n log n), wie Klotzkopp schon erwähnt hat. Zitieren
Klotzkopp Geschrieben 15. Mai 2008 Geschrieben 15. Mai 2008 Da es iterativ ist ergibt sich formal doch O(c*n) = O(n)Wenn du auf die ganzen Zahlen zugreifen könntest, ja. Du kannst aber nur auf einzelne Bits zugreifen. Damit ist die Addition zweier Zahlen nicht mehr in konstanter Zeit möglich, sondern hängt linear von der Anzahl der Bits ab. Die wiederum hängt vom Logarithmus der Anzahl der Zahlen ab. Zitieren
flashpixx Geschrieben 15. Mai 2008 Geschrieben 15. Mai 2008 Hallo, ich hab das mit den "Bits" überlesen. Sorry Phil Zitieren
Jan Jansen Geschrieben 15. Mai 2008 Geschrieben 15. Mai 2008 Wie wäre folgende Lösung: 1. Durchsuche das Array nach gerade und ungerade (letztes Bit) und schreibe die Positionen je nach Gerade/Ungerade in ein eigenes Array 2. Anhand der Anzahl Gerade/Ungerade kann man bestimmen ob die gesuchte Zahl Gerade/Ungerade ist -> 1. Stelle gefunden, n Lesevorgänge 3. Suche in der eingeschränkten Ausgangsmenge (Zugriff über das Gerade oder Ungerade-Array) jetzt nach der 2. Stelle und speicher die Positionen wieder in 2 unterschiedlichen Array Je nach Anzahl kann man wieder bestimmen ob das 2. Bit Gerade/Ungerade ist -> 2. Stelle gefunden, aber nur noch 1/2*n Lesevorgänge So geht man alle Stellen durch und verkleinert die Restmenge der Zahlen die durchsucht werden muss immer um 1/2 n + 1/2*n + 1/4*n ... = n*(1+1/2+1/4 ...) das wäre ein Aufwand der Ordnung n Zitieren
smoon Geschrieben 15. Mai 2008 Autor Geschrieben 15. Mai 2008 Dies scheitert schon am dynamischen erstellen der Arrays nach jedem Durchgang. Zitieren
Jan Jansen Geschrieben 15. Mai 2008 Geschrieben 15. Mai 2008 (bearbeitet) Naja, es geht ja weniger um die Technik, als um einen Algorithmus um dein Problem zu lösen. Ob du jetzt die Werte in einem Array merkst, einem File, einer verketten Liste sollte eigentlich egal sein Bearbeitet 15. Mai 2008 von Jan Jansen Zitieren
smoon Geschrieben 15. Mai 2008 Autor Geschrieben 15. Mai 2008 Dennoch bin ich der Meinung das dieser Algorithmus nicht die Komplexität O(n) hat, denn du wiederholst ja die Schritte (log n)-Mal. Also wäre es doch wieder O(n log n). Bitte korrigiert mich falls ich falsch liege! Zitieren
Klotzkopp Geschrieben 15. Mai 2008 Geschrieben 15. Mai 2008 Ob du jetzt die Werte in einem Array merkst, einem File, einer verketten Liste sollte eigentlich egal seinDas Problem bleibt aber, dass man nicht auf einen ganzen Wert zugreifen kann, nur auf einzelne Bits. Man kann also die Werte auch nicht in konstanter Zeit umkopieren. Zitieren
smoon Geschrieben 15. Mai 2008 Autor Geschrieben 15. Mai 2008 Ich glaub er meinte nicht das man die Bits umkopiert, sondern sich lediglich jeweils die Positionen der gerade/ungerade werte "merkt". Zitieren
flashpixx Geschrieben 15. Mai 2008 Geschrieben 15. Mai 2008 Hallo nochmal, was soll eigentlich genau gemacht werden? Ich habe das Ursprungsposting noch mal gelesen. Die Beschränkung ist klar, ich kann immer nur ein Bit in const. Zeit lesen. Ist jetzt die Fragestellung: Gib es einen Algorithmus mit O(c*n), mit dem man prüfen kann, ob alle Zahlen von 0 bis n-1 vorhanden sind?Muss man diese Aufgabenstellung implementieren z.B. Pseudocode?Ist zu zeigen, dass es diesen Algorithmus gibt, d.h. ein allgemein gültigen Beweis zu führen bzw. ihn zu widerlegen? Phil Zitieren
smoon Geschrieben 15. Mai 2008 Autor Geschrieben 15. Mai 2008 Ist jetzt die Fragestellung: Gib es einen Algorithmus mit O(c*n), mit dem man prüfen kann, ob alle Zahlen von 0 bis n-1 vorhanden sind?Muss man diese Aufgabenstellung implementieren z.B. Pseudocode?Ist zu zeigen, dass es diesen Algorithmus gibt, d.h. ein allgemein gültigen Beweis zu führen bzw. ihn zu widerlegen? Nein es soll die Fehlende Zahl im Array ermittelt werden, in O(n).Ja der Algorithmus soll in Pseudocode implementiert werden.Nein es ist nichts zu beweisen. Zitieren
Jan Jansen Geschrieben 16. Mai 2008 Geschrieben 16. Mai 2008 Dennoch bin ich der Meinung das dieser Algorithmus nicht die Komplexität O(n) hat, denn du wiederholst ja die Schritte (log n)-Mal. Also wäre es doch wieder O(n log n). Bitte korrigiert mich falls ich falsch liege! Der Aufwand für jeden Schritt wird aber erheblich kleiner Die Anzahl der Summanden in der Klammer ist abhängig von n bzw. von der Anzahl der Bits n + 1/2*n + 1/4*n ... = n*(1+1/2+1/4 +1/8+1/16 ...) für mich läuft dieser Wert (bei sehr großen n) auf eine Konstante heraus, laut Wikipedia/Englisch konvergiert er auf 1+1=2 Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.