Elemente zählen < Java < Programmiersprachen < Praxis < Informatik < Vorhilfe
|
Status: |
(Frage) beantwortet | Datum: | 19:19 Do 12.01.2012 | Autor: | mikexx |
Aufgabe | Hallo, ich will gerade eine Methode schreiben, die die Elemente einer doppelt verketten Liste (ohne das Ankerelement mitzuzählen) zählt.
Ich weiß aber gerade nicht, wie... |
Also ich kann wegen der Ringstruktur und der doppelten Verkettung irgendwo anfangen zu zählen...
Ich hätte an sowas gedacht, aber das kann nicht stimmen:
1: | public int size(){
| 2: | int counter = 0;
| 3: | RList e = this;
| 4: |
| 5: |
| 6: | while (e.n != e){
| 7: | counter++;
| 8: | e=e.n;
| 9: | }
| 10: |
| 11: | return counter;
| 12: |
| 13: | } |
wobei n die Referenz auf das Folgeelement ist.
Aber das kann ja nicht stimmen... so würde das ja nie abbrechen... ;(
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 19:33 Do 12.01.2012 | Autor: | mikexx |
Ich weiß nicht, wie ich das Element, auf das man die Methode anwendet zwischenspeichern kann; normalerweise hätte ichs halt mit this gemacht..
aber wenn ich das this doch dann in der while-Schleife immer eins weiterschiebe, klappt das doch nicht...
|
|
|
|
|
Status: |
(Antwort) fertig | Datum: | 19:54 Do 12.01.2012 | Autor: | rainerS |
Hallo!
> Hallo, ich will gerade eine Methode schreiben, die die
> Elemente einer doppelt verketten Liste (ohne das
> Ankerelement mitzuzählen) zählt.
>
> Ich weiß aber gerade nicht, wie...
> Also ich kann wegen der Ringstruktur und der doppelten
> Verkettung irgendwo anfangen zu zählen...
>
> Ich hätte an sowas gedacht, aber das kann nicht stimmen:
>
1: | public int size(){
| 2: | int counter = 0;
| 3: | RList e = this;
| 4: |
| 5: |
| 6: | while (e.n != e){
| 7: | counter++;
| 8: | e=e.n;
| 9: | }
| 10: |
| 11: | return counter;
| 12: |
| 13: | } |
>
>
> wobei n die Referenz auf das Folgeelement ist.
>
>
> Aber das kann ja nicht stimmen... so würde das ja nie
> abbrechen... ;(
Richtig erkannt Du musst abbrechen, wenn du wieder an der Stelle angekommen bist, mit der du begonnen hast, und das ist nicht wenn e.n == e ist, sondern e.n == this . Allerdings bricht du dann ein Element zu früh ab, oder?
Und wie ist das mit dem Spezialfall einer leeren Liste?
Viele Grüße
Rainer
|
|
|
|
|
Status: |
(Frage) beantwortet | Datum: | 19:59 Do 12.01.2012 | Autor: | mikexx |
> Richtig erkannt Du musst abbrechen, wenn du wieder an
> der Stelle angekommen bist, mit der du begonnen hast, und
> das ist nicht wenn e.n == e ist, sondern e.n == this .
> Allerdings bricht du dann ein Element zu früh ab, oder?
Meinst Du also:
Bei der while-Schleife:
1: | while(e.n !=this){
| 2: |
| 3: | ...} | ?
Ja, stimmt, ein Element zu früh, bricht man dann ab...
Und wie ist das mit dem this, also e? Das wird doch immer eins weiter verschoben..?!
Weißt du eine bessere Idee?
Und wegen der leeren Menge, die ist nur durch das Ankerlement repräsentiert und bei diesem sind Referenz auf Vorgänger und Nachfolger dann auf das Ankerelement selbst gerichtet. Würde dann nicht die while-Schleife übersprungen und 0 ausgegeben, wie es auch sein soll?
>
> Und wie ist das mit dem Spezialfall einer leeren Liste?
>
> Viele Grüße
> Rainer
>
|
|
|
|
|
Status: |
(Antwort) fertig | Datum: | 20:23 Do 12.01.2012 | Autor: | rainerS |
Hallo!
>
> > Richtig erkannt Du musst abbrechen, wenn du wieder an
> > der Stelle angekommen bist, mit der du begonnen hast, und
> > das ist nicht wenn e.n == e ist, sondern e.n == this .
> > Allerdings bricht du dann ein Element zu früh ab, oder?
>
>
> Meinst Du also:
>
> Bei der while-Schleife:
>
> 1: | while(e.n !=this){
| 2: | >
| 3: | > ...} | ?
>
> Ja, stimmt, ein Element zu früh, bricht man dann ab...
>
> Und wie ist das mit dem this, also e? Das wird doch immer
> eins weiter verschoben..?!
Also erstens weist du nur e einen neuen Wert zu. Wenn ich schreibe
e=f;
e=neuerWert;
dann ändert sich f doch nicht.
Außerdem kannst du this nicht verändern, das referenziert immer die aktuelle Objektinstanz.
>
> Weißt du eine bessere Idee?
Einfach counter+1 zurückgeben?
> Und wegen der leeren Menge, die ist nur durch das
> Ankerlement repräsentiert und bei diesem sind Referenz auf
> Vorgänger und Nachfolger dann auf das Ankerelement selbst
> gerichtet. Würde dann nicht die while-Schleife
> übersprungen und 0 ausgegeben, wie es auch sein soll?
Korrekt, aber wie wir gerade festgestellt haben, wird in allen anderen Fällen 1 zu wenig zurückgegeben. Mit anderen Worten: wenn counter hinter der Schleife den Wert 0 hat, weisst du nicht, ob deine Liste Länge 0 oder 1 hat.
Viele Grüße
Rainer
|
|
|
|
|
Status: |
(Frage) beantwortet | Datum: | 20:26 Do 12.01.2012 | Autor: | mikexx |
Aber counter+1 kann es doch auch nicht sein...
Mal angenommen die Liste sieht so aus:
Anker - Eintrag 1 - Eintrag 2
und ich beginne zu zählen bei Eintrag 1.
Dann würde bei counter+1 doch drei ausgegeben, es soll ja aber zwei herauskommen, weil man das Ankerelement nicht mitzählen soll.
|
|
|
|
|
Status: |
(Antwort) fertig | Datum: | 20:33 Do 12.01.2012 | Autor: | rainerS |
Hallo!
> Aber counter+1 kann es doch auch nicht sein...
>
> Mal angenommen die Liste sieht so aus:
>
> Anker - Eintrag 1 - Eintrag 2
>
> und ich beginne zu zählen bei Eintrag 1.
>
> Dann würde bei counter+1 doch drei ausgegeben, es soll ja
> aber zwei herauskommen, weil man das Ankerelement nicht
> mitzählen soll.
Ah,OK stimmt, das hatte ich übersehen. Eine Liste mit nur dem Ankerelement ist per Definition die leere Liste? Dann reicht es tatsächlich, while(e.n!=this) {..} zu schreiben.
Viele Grüße
Rainer
|
|
|
|
|
Status: |
(Frage) beantwortet | Datum: | 20:36 Do 12.01.2012 | Autor: | mikexx |
Also wörtlich heißt es:
"Die leere Liste wird allein durch das Ankerelement repräsentiert, bei dem Nachfolger und Vorgänger auf sich selbst zeigen."
Ich hätte sonst noch dies anzubieten:
1: | public int size() {
| 2: | int counter=0;
| 3: | RList e = this;
| 4: |
| 5: | if(e.n == this){
| 6: | return counter;
| 7: | }
| 8: |
| 9: | while(e.n != this){
| 10: | counter++;
| 11: | e = e.n;
| 12: | }
| 13: | return counter;
| 14: | } |
|
|
|
|
|
Hallo mikexx,
> Also wörtlich heißt es:
>
> "Die leere Liste wird allein durch das Ankerelement
> repräsentiert, bei dem Nachfolger und Vorgänger auf sich
> selbst zeigen."
>
>
> Ich hätte sonst noch dies anzubieten:
>
> 1: | public int size() {
| 2: | > int counter=0;
| 3: | > RList e = this;
| 4: | >
| 5: | > if(e.n == this){
| 6: | > return counter;
| 7: | > }
| 8: | >
| 9: | > while(e.n != this){
| 10: | > counter++;
| 11: | > e = e.n;
| 12: | > }
| 13: | > return counter;
| 14: | > } |
Das ist auch ok.
Gruss
MathePower
|
|
|
|
|
Status: |
(Frage) beantwortet | Datum: | 20:57 Do 12.01.2012 | Autor: | mikexx |
Aber das hier:
1: | public int size() {
| 2: | int counter=0;
| 3: | RList e = this;
| 4: |
| 5: | while(e.n != this){
| 6: | counter++;
| 7: | e = e.n;
| 8: | }
| 9: | return counter;
| 10: | } |
ist schon eleganter, oder?
|
|
|
|
|
Hallo mikexx,
> Aber das hier:
>
> 1: | public int size() {
| 2: | > int counter=0;
| 3: | > RList e = this;
| 4: | >
| 5: | > while(e.n != this){
| 6: | > counter++;
| 7: | > e = e.n;
| 8: | > }
| 9: | > return counter;
| 10: | > } |
>
> ist schon eleganter, oder?
Ja.
Gruss
MathePower
|
|
|
|
|
Status: |
(Frage) überfällig | Datum: | 12:00 Fr 13.01.2012 | Autor: | mikexx |
Hallo, es soll nun eine Methode add(T d) implementiert werden, die ein Element hinter das Element in die Liste einfügt, auf das die Methode angewandt wird. Dabei ist add(null) nicht zulässig, da sonst das Ankerelement nicht eindeutig bestimmbar wäre.
Dabei soll kein if-statement verwendet werden, was mir momentan völlig schleierhaft ist, wie das funktionieren kann. Ich bin nämlich bis jetzt lediglich darauf gekommen, daß man wohl drei Fälle unterscheiden muss:
1. Fall: Man hat eine leere Liste vorliegen, d.h. wendet die Methode auf das Ankerelement an.
2. Fall (a): Man hat eine nich-leere Liste vorliegen und wendet die Methode auf ein Element an, das nicht das letzte Element der Liste ist.
2. Fall (b): Man wendet die Methode auf das letzte Listenelement an.
Die entsprechenden Codes sehen bei mir so aus:
1. Fall:
1: | public void add(T d){
| 2: | if(d != null){
| 3: | this.n = d;
| 4: | this.p = d;
| 5: | d.n = this;
| 6: | d.p = this;
| 7: | }
| 8: | } |
2. Fall (a):
1: | public void add(T d){
| 2: | if(d != null){
| 3: | this.n = d;
| 4: | d.p = this;
| 5: | d.n = this.n;
| 6: | this.n.p = d;
| 7: | }
| 8: | } |
2. Fall (b):
1: | public void add(T d){
| 2: | if(d != null){
| 3: | this.n = d;
| 4: | d.p = this;
| 5: | d.n = this.n;
| 6: | }
| 7: | } |
Ich frage mich erstens, ob diese Einzelfälle so stimmen und zweitens, wie man dies alles zusammenbringen kann und das auch noch ohne ein if-statement.
Kann und mag mir jemand vielleicht weiterhelfen?
Dankeschön für alle Mühe!
LG, mikexx
|
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 12:26 Fr 13.01.2012 | Autor: | mikexx |
Ich hab' (glaube ich) nicht klar genug drüber nachgedacht.
Wenn ich mir alle drei Fälle ein bisschen genauer ansehe, so müsste für alle drei Fälle dieser Code zutreffen:
1: | public void add(T d){
| 2: | if(d != null){
| 3: | this.n = d;
| 4: | d.p = this.n;
| 5: | d.n = this.n;
| 6: | this.n.p = d;
| 7: | }
| 8: | } |
Würde mir da jemand zustimmen?
Und wie könnte ich auch noch das übriggebliebene if-statement wegbekommen?
|
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 12:20 So 15.01.2012 | Autor: | matux |
$MATUXTEXT(ueberfaellige_frage)
|
|
|
|