2 Arrays in 1 Liste sortieren

Status
Nicht offen für weitere Antworten.

T-Bone

Mitglied
Hey Folks
Ich sitze hier an einer Aufgabe zu Arrays und Listen. Keine Angst, ich möchte keine Musterlösung von jemandem 😛

Habe nur Verständnissprobleme zu einigen Sachen.

Sind 2 Arrays gegeben, die man mit Hilfe von einer Methode in einer sortierte Liste packen soll um diese Liste dann zurückzugeben. --->>
Programmieren Sie den Rumpf einer Methode Liste L(int[] a, int[] b), so dass L
eine aufsteigend sortierte Liste liefert, die alle Zahlen enthält, die
· sowohl im Array a vorkommen
· als auch im Array b vorkommen
· und positiv und zweiziffrig sind (d.h. im Intervall [10, 99] liegen).


Das hier ist die vorgegebene Musterlösung. Mein Problem ist nun was die boolschen Ausdrücke hier zu suchen haben. Ich hätte es ohne versucht. Kam so aber auch nicht gross weiter.
Code:
{ int i; Liste y = new Liste();
for (int z = 10; z <= 99; z++ )
{ boolean va = false, vb = false;
for (i = 0; i < a.length; i++ ) va = va || z == a[i];
for (i = 0; i < b.length; i++ ) vb = vb || z == b[i];
if (va && vb)
if (y.Kopf == null) y.Kopf = y.Fuss = new Element(z);
else y.Fuss = y.Fuss.Nf = new Element(z);
}
return y;
}
wenn ihrs erklären könntet, wieso
va=va || z == a ....
wäre ich euch echt dankbar 🙂

Ich setze mich jetzt nochmal an meine Lösung ohne die boolschen Ausdrücke und werde sie posten a.s.a.p

Gruss
 
Code:
for (i = 0; i < a.length; i++ ) va = va || z == a[i];
for (i = 0; i < b.length; i++ ) vb = vb || z == b[i];

Hä das geht doch garnicht oder ??

Code:
va = va

Das ist ja noch nichtmal ein boolscher Ausdruck. Ich kapier selber nicht was das überhaupt soll. Die 2 Zeilen erschließen sich mir nicht 😉
 
Code:
int[] a = ...;
int[] b = ...;
Collection<Integer> liste = new TreeSet<Integer>();
for(int i=0; i<a.length; i++) {
  liste.add(a[i]);
}
for(int i=0; i<b.length; i++) {
  liste.add(b[i]);
}
 
Ja das genau ist auch mein Problem.

die for-Schleife geht ja die zahlenbereiche von 10 bis 99 durch, und schaut bei jedem Durchgang an allen Stellen der beiden Arrays ob die 10, 11, 12 .. usw vorhanden sind.

Wenn jetzt die 14 gesucht wird und in dem Array a an irgendeiner Stelle die 14 gefunden wird, wird zwar va=va gesetzt (false=false) aber durch die || (oder-verknüpfung) wird der zweite Ausdruck genommen. Sprich z==a ist an der Stelle ja (true), wo das Array die 14 hat.
Das gleiche wird bei dem Array []b geprüft.
Und dann weitergegeben zu der
Code:
if (va && vb)
if (y.Kopf == null) y.Kopf = y.Fuss = new Element(z);
else y.Fuss = y.Fuss.Nf = new Element(z);

Ich bin jetzt einfach mal die Schritte im Kopf durchgegangen, habe aber keinen Schimmer ob das richtig ist. Bleibe da leider auch hängen.

Und wenn der DOKTOR schon ins schwanken kommt :bae:

Was mich ebenfalls irritiert ist; das bei
Code:
va = va || z == a[i];
immer weitergemacht wird. weil selbst wenn z!=a ist, ist ja immer noch va=va.
Wenn das nicht schon die Musterkösung wäre würd ich ja sagen "schauste mal weiter bis du nen anderen Weg findest..."

Sieht so aus, als seien mehr Meinungen gefragt ;-)
 
Also wenn das die Musterlösung ist gute Nacht 😉

Ich hätte erstmal die zwei Arrays in eine Liste geschmissen und die Liste dann sortiert mit BubbleSort-Verfahren, wenn dir das schon was sagt. Die da angegebene Lösung ist meines Wissens noch nichtmal kompilierbar (selbst wenn man die offensichtlichen Fehler weglässt).
 
T-Bone hat gesagt.:
Code:
{ int i; Liste y = new Liste();
for (int z = 10; z <= 99; z++ )
{ boolean va = false, vb = false;
for (i = 0; i < a.length; i++ ) va = va || z == a[i];
for (i = 0; i < b.length; i++ ) vb = vb || z == b[i];
if (va && vb)
if (y.Kopf == null) y.Kopf = y.Fuss = new Element(z);
else y.Fuss = y.Fuss.Nf = new Element(z);
}
return y;
}
Das soll die Musterlösung sein :shock:
Naja, werde trotzdem mal auseinanderpflücken.

In der äußeren Schleife über alle möglichen Werte wird getestet
ob der aktuelle Wert in einer der beiden arrays enthalten ist.
Die Anweisung va = va || z == a; ist zwar richtig aber auch Schwachsinn.
Der boolean va (Vorhanden in array a) bleibt true falls er es vorher
schon war (der aktuelle Wert also schon in dem array a gefunden wurde) oder sonst
das aktuelle a gleich diesem Wert ist.

Wenn der Wert aber schon gefunden wurde, macht es keinen Sinn, den Rest
des arrays zu durchsuchen; man kann gleich aus den inneren
Schleifen springen.

Der Rest der Methode trägt den Wert genau dann ein, wenn er
in beiden arrays vorkam. if (va && vb)
Die letzte if-Anweisung wird gebraucht um eine korrekte Eintragung vorzumehmen,
abhängig davon ob die Liste leer ist oder nicht.
 
byto hat gesagt.:
Doktor Ruff hat gesagt.:
Ich hätte erstmal die zwei Arrays in eine Liste geschmissen und die Liste dann sortiert mit BubbleSort-Verfahren

Oder einfach ein Set verwenden...

Die Methode soll aber eine verkette Liste zurückgeben. Der Kopf der Methode ist ja schon gegeben.

EDIT:
Oh ich sehe gerade, dass die Zahlen zwischen 10 und 99 liegen müssen. In dem Fall musst du bevor du die Elemente der Arrays in die Liste schmeisst noch abfragen, ob diese größer als 9 und kleiner als 100 sind.
Die Liste musst du dann natürlich noch sortieren wie oben schon erwähnt. Ich kann ja mal genau eine solche Methode basteln wenn du willst.
 
genau zurückgegeben soll eine Liste werde mit Kopf und Fuss verweisen ...

Aber du hattest recht Leroy.Den boolean brauchen wir ja um zu sehen, dass auch beide arrays die Zahlen enthalten! und sobald die zahl im ersten array gefunden wurde wird sie auf true gesetzt und aufgehört weiterzusuchen. und beim 2tenarray das Gleiche ... und dann wird geschaut ob auch echt va==vb sind. sprich ob beide auf true gesetzt wurden. Weil nur dann wollen wir ja die zahl in unsere Liste übernehmen .

nur warum>>
Code:
va = va || z == a[i];
<< reicht va=va nicht aus ?!

alles andere ab
Code:
 if (va && vb)
ist ja auch wieder klar.

Dann sach ich mal danke :toll:
 
Ich glaube hier gibt es entscheidende Mißverständnisse bei der Bedeutung
der Anweisung
Code:
 va = va || z == a[i];
Zum besseren Verständnis überklammere ich mal:
va = (va || (z == a));

Also va bekommt zugewiesen den Wert von va oder sonst den
Wert des Ausdrucks z==a.

Oder sonst bedeutet hier, daß nicht einfach ein die oder -Operation
aufgerufen wird, sondern der 2. Term überhaupt nur dann ausgewertet
wird, wenn das Ergebnis des Gesamtterms noch nicht feststeht. Wenn also
va bereits true ist, wird der 2. Term also gar nicht ausgewertet, weil das
Ergebnis sowieso true bleibt.

In Worten bedeutet diese Anweisung also
VorhandenInA = BereitsVorhandenInA oder sonst jetztGefunden

Die Anweisungen sind also vollkommen korrekt bzgl. dem was sie machen
sollen. Es ist eben nur unnötig den Rest eines Arrays zu durchsuchen sobald
va das erste mal true geworden ist.

Desweiteren könnte ich mir denken, daß diese direkte Lösung auch
recht effizient ist verglichen mit Umwegen über Sets, Sortieren, ...

Da lasse ich mich aber gerne eines Besseren belehren. 😎
 
Oh man jetzt komme ich selbst ins schlingern. Ich ralle die Zeile aber immer noch nicht:

Code:
va = va || z == a[i];

was wird denn va zugewiesen wenn va true und z == a false ist???

Sowas hab ich noch nie gesehen? Vielleicht kann da mal einer Klammern setzen oder so, sonst steig ich da nicht durch. Oder ist der Code da ne Kurzform für irgendwas?

EDIT: OH da war wohl jemand schneller und hat meine Frage vorausgeahnt (gutes Gespühr, du solltest Lehrer werden 😉 )
 
T-Bone hat gesagt.:
sobald die zahl im ersten array gefunden wurde wird sie auf true gesetzt und aufgehört weiterzusuchen
Fast! Es wird zwar nicht mehr gesucht, da keine Vergleiche mit den restlichen array-Elementen
ausgeführt werden. Dennoch wird die Schleife sinnlos bis zum bitteren Ende weiterdurchlaufen.

T-Bone hat gesagt.:
und dann wird geschaut ob auch echt va==vb sind. sprich ob beide auf true gesetzt wurden.

va==vb wäre aber auch dann true wenn beide false sind. Es würden dann also alle Zahlen
in die Liste aufgenommen, die entweder in beiden arrays vorkommen oder die überhaupt
nicht vorkommen.

va && vb ist in der Musterlösung also schon richtig.
 
hm ja gut ich glaub ich habs. danke schön euch allen.

Ich hab jetzt hier mal mein Programm fertig gemacht. Zeigt nur leider noch nicht alle richtigen Zahlen an(14 25 31 66)
Aber verstanden hab ichs soweit schonmal 🙂

Code:
public class Main{
    public static void main(String[]args){
        int []a={25,7,14,31,66,14,15};
        int []b={55,31,25,66,14,14,7,14,66};
        
        Liste komprimiert=new Liste();
        Liste test=new Liste();
        test=komprimiert.L(a, b);
        test.print();
    }
}

class Liste{
    Element Kopf, Fuss;
    Liste(){
        Kopf=Fuss=null;
    }
    Liste L(int[] a, int[] b){ 
        int i; Liste y = new Liste();
        for (int z = 10; z <= 99; z++ ){ 
            boolean va = false, vb = false;
            for (i = 0; i < a.length; i++ ) va = va || z == a[i];
            for (i = 0; i < b.length; i++ ) vb = vb || z == b[i];
            if (va && vb)
                if (y.Kopf == null) y.Kopf = y.Fuss = new Element(z);
                else y.Fuss = y.Fuss.Nf = new Element(z);
        }
        return y;
    }
    
    void print(){
        Element temp=Kopf;
        if (Kopf==Fuss&&Kopf==null) System.out.println("Es sind keine Elemente verfügbar!");
        else if(Kopf==Fuss&&Kopf!=null) System.out.println("Nur ein Objekt vorhanden: " + Kopf.Zahl);
        else{
            for(temp=Kopf; temp!=Fuss; temp=temp.Nf){
                System.out.println(temp.Zahl);
                temp=temp.Nf;
            }
        }
    }
}

class Element{
    int Zahl;
    Element Nf;
    Element(int Zahl){
        this.Zahl=Zahl;
    }
}
Output ist dabei:
14
31
Exception in thread "main" java.lang.NullPointerException
at Liste.print(Main.java:37)
at Main.main(Main.java:9)
Java Result: 1
 
OT: Der Code spielt in der Liga "worst code ever" ganz weit oben mit. :roll: Entferne noch die Einrückung und Dir ist ein Spitzenplatz sicher. 😉
 
Irgendwie ist deine print-Methode etwas verwuselt. Ohne sie zu analysieren
biete ich dir eine andere an
Code:
    void print(){
		if (Kopf == null)
			System.out.println("Es sind keine Elemente verfügbar!");
		else if (Kopf == Fuss)
			System.out.println("Nur ein Objekt vorhanden: " + Kopf.Zahl);
		else {
			for (Element temp = Kopf; temp != null; temp = temp.Nf)
				System.out.println(temp.Zahl);
		}
    }
 
dann sach ich mal danke schön ???:L

ich konnte grade nur nicht wirklich einen kreativen Ansatz in deinem Thread finden.
Ich hätte ihn jetzt als grund solide eingestuf. nicht viel schnickschnack aber alles was man braucht.

eine Klasse um die ELEMENTE in der Liste zu deklarieren
eine Klasse LISTE wo die Methoden drin stehen
und die MAIN wodrüber ich die listen erstelle .......

Ich meine das sind die Anfänge wie sie einem gelehrt werden.

Danke für die PRINT methode:
Code:
void print(){
      if (Kopf == null)
         System.out.println("Es sind keine Elemente verfügbar!");
      else if (Kopf == Fuss)
         System.out.println("Nur ein Objekt vorhanden: " + Kopf.Zahl);
      else {
         for (Element temp = Kopf; temp != null; temp = temp.Nf)
            System.out.println(temp.Zahl);
      }
    }
die läuft einwandfrei. 🙂
 
Noch ein Tipp zu diesen Zeilen.

Code:
        Liste komprimiert=new Liste(); 
        Liste test=new Liste(); 
        test=komprimiert.L(a, b); 
        test.print();

Du definierst 2 Listen deren Inhalt dich gar nicht interessiert. Dann benutzt du
die eine Liste (komprimiert) um eine neue Liste zu erzeugen die du dann
der anderen Referenz (test) zuweist. Diese gibt sich dann selbst aus. Das ist ok.

Irgendwie sieht es aus als konntest du dich nicht so recht entscheiden wo und
wie die Zusammenführungsmethode L überhaupt arbeiten soll.

Ich schlage 2 Möglichkeiten vor:
1) Die Methode arbeitet eigentlich nur auf Listen. Dann kann sollte sie entweder
eine statische Methode der Klasse Liste sein oder sie muß gar nicht in der Klasse
selbst stehen.

2) Die Methode verändert eine existierende Liste (vielleicht auch leere Liste).
Dann kann sie schon eine Instanzmethode sein, braucht aber keinen Wert zurückgeben
und erzeugt auch keine neue Liste.


Noch etwas: Es macht Sinn sich früh an die Code-Konventionen zu orientieren.

Methodennamen immer klein beginnen.
Variablennamen immer klein beginnen.
Klassennamen immer groß beginnen.
 
ja an die ganzen formsachen muss ich mich in der Tat noch dran gewöhnen..

und so ist jetzt auch nur noch eine Variable LISTE draus entstanden
Code:
        Liste komprimiert=new Liste();
        komprimiert.L(a, b);
        komprimierte.print();
🙂

Ihr seid wirklich sehr hilfsbereit und vor allem schnell hier. :toll:
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben