Java-Methode, die ihre erfolgreiche Ausführung mitteilt?

bernd

Neues Mitglied
Hallo,
ich habe ein Array int[] a sowie eine "Matrix" int[][] matrix, welche als Array von Array zu verstehen sei.

Nun will ich jede "Zeile" dieser Matrix nehmen und gucken ob ich da das a einfügen kann. falls es geht, füge es ein.
habe ich natürlich shcon a in eine zeile eingefügt, brauche ich die nachfolgenden zeilen gar nicht mehr zu betrachten und kann direkt abbrechen.

Programmiertechnisch sieht das bei mir so aus:
Java:
public void einfuegen(int[] array; int[][] matrix) {
  for (int[] zelle : matrix) {
    if (einfuegbar(array, zelle)) {
      einfuegen(array, zelle);
      return;
    }
  }
}

einfuegbar(int[]a,int[]b) ist einfach eine methode die zurückgibt als bool wert ob das array a in das array b "eingefügt" werden kann.
einfuegen(a,b) wiederum ist eine methode mit rückgabewert void, die selbiges einfügen durchführt.

wie man die ei fügbarkeit prüft und wie man es einfügt, hat mit den randbedingungen meines programm s zu tun und das zu programmieren ist kein problem.


nur nervt mich in meinem obigen programm der part
Java:
if (einfuegbar(array, zelle)) {

  einfuegen(array, zelle);

  return true;
}

weil hier wird erst geprüft ob es einfügbar ist.
dann wird die einfügbarkeit durchgeführt.
und dann wird zurückgegeben dass, falls dem so ist, erfolgreich eingefügt wurde und damit insbesodnere die umgebende methode abrupt abgebrochen wird.

irgendwie stört mich diese zu kleinliche zerlegung in einzelaufgaben und ich hätte gerne eine einzige methode gebastelt, die in sich prüft ob einfügbar, falls zutreffend die einfügung macht und den "erfolg" oder nicht erfolg der einfügung als rückgabe wert zurückgibt.

also eine methode wie etwa
Code:
public bool einfügen (int[] a, int[] b){
  bool p=#einfügbarkeitskriterium;
  if (p){
      //einfügungskram
     return true;
  }
  return false;
}



Frage ich nur, kann ich das irgendwie mit meinem ursprünglichen code (siehe erster code block) benutzen und wenn ja, wie?

ich hätte eigentlich an sowas wie "return einfügen(array,zeile)" gedacht.
Nur befürchte ich dabei, dass wenn in einem der Durchgänge die einfügen Methode aufgerufen wird und false als rückgabe wert liefert, dass dann trotzdem die gesamtmethode dort abgebrochen wird wegen des "return false".
obwohl ich ja will dass die ursprungsmethode nur dann abgebrochen wird wenn in einem der durchläufe ein erfolgreicher einfügevorgang durchgeführt wird.
also nur im fall wo wir true als rückgabe wert haben, abgebrochen wird.


oder sollte ich da als "abbruchbedingung" vielleicht sowas schreiben wie
Code:
if (einfügen(array1,array2)){
return;
}


oder wie würde ich das da richtig benutzen?
sodass nur bei aufrufen der einfügenmethode mit rückgabewert true alles abgebrochen wirde?
 
Eine Methode bool zurückgeben lassen ist in so einem Fall schon der richtige Weg.
Generell solltest du nur in Ausnahmefällen void als Rückgabetyp haben, das weißt immer auf ein suboptimales Programmdesign hin. Eine Alternative, für den Fall dass "Kann nicht eingefügt werden" einen Fehlerfall des Programmes darstellt, wäre natürlich, in diesem Fall eine Exception zu werfen und sie im aufrufenden Code entsprechend zu behandeln.

Für dein Bool-Problem wäre eine mögliche Lösung folgende(angenommen, die Funktion gibt true zurück, wenn das Einfügen erfolgreich war, und sonst false):
Java:
public bool insert(int[] arr, int[][] mat) {
  for (int[] cell : mat) {
    if (!insertable(cell, arr)) {
      return false
    } else {
      ins_1(arr, cell);
    }
  }
  return true;
}

So brichst du so früh wie möglich ab, wenn es nicht klappt, und wenn jedes der einzelnen Inserts funktioniert hat wird ein true zurück gegeben(wenn ins_1 eine Exception werfen könnte oder so wäre das noch etwas komplexer). Ich hab dein zweites "einfügen" mal anders genant(ins_1), dein Code wäre sonst , wie ich annehme ungewollt, rekursiv.

MfG
 
Ich sollte vielleicht kurz die Hinergründe meines Gesamtplans erklären:
Im Endeffekt will ich gucken wie ich alle möglichen 3er Lottozahlenblöcke in so wenig wie möglich 6-zahlen-blöcke einfügen kann.

Ziel ist es , am Ende eine Menge an 6ertipps zu haben, die, wenn ich sie alle tippe, mir garantiert 3 richtige gibt.

Also alle nur denkbaren 3er kombinationen abdeckt.

hierzu will ich sugzessive die nötigen 6er reihen aufbauen, immer bedacht auf so wenig platzverbrauch wie nötig.


die ersten 3er zahlen sind
(1,2,3)
(1,2,4)
...
(1,2,49)
(1,3,1)
usw.


zu beginn habe ich eine komplett leere liste an 6er tipps.
ich nehme mir also die erste 3er zahl (1,2,3) her.
weil noch keine 6er tipps existieren, erzeuge ich mir einen neuen und füge in diesen direkt die (1,2,3) ein.
liste der 6ertipps aktuell:
{(1,2,3,0,0,0)}
(0 soll hier als platzhalter stheen für noch nicht verwendete stellen eines 6 tupels.

dann nehmen wir die nächste 3er zahl (1,2,4)
wir müssen nun prüfen ob es sich in die schon vorhandenen 6er tupels integrieren lässt.
falls nein, müssten wir einen neuen 6tuel einfügen und dort die zahlen reinpacken.

wir gucken also konkret:
passt (1,2,4) in (1,2,3,0,0,0) rein?
ja.
da wir keine zahl (innerhalb eines 6er tupels) doppelt haben wollen, gucken wir konkret wie viele gemeinsame zahlen die 2 tupel haben und ob es unter nichthinzufügen der doppelten zahlen reicht um es einzufügen.
wir gucken also:
1 ist shcon drin, braucht nicht hinzugefügt zu werden.
2 ist auch shcon drin.
die 4 hingegen ist noch nicht drin, ist also eine neue zahl.
das 3tupel hat also eine "unique number" und im 6er tupel waren noch 3 stellen (aka die 3 nullstellen) frei.
3 leerstellen>1neue zahl, also können wir es einfügen.

demnach fügen wir die 4 an die erste leere stelle ein.
unsere 6tupel lsite sieht nun so aus
{(1,2,3,4,0,0)}
ähnlich fügen wir
(1,2,5)und (1,2,6) ein.
Ergebnis:
{(1,2,3,4,5,6)}

Nun wirds heikel.
Als nächste ist (1,2,7) einzufügen.
wir gucken wieder unsere schon vorhandenen 6tupel an:
(1,2,3,4,5,6) und (1,2,7) haben 2 gmeeinsame zahlen, also 1 unique number einzufügen.
allerdings hat (1,2,3,4,5,6) keine leerstellen. 0!>1 (0 nicht größer gleich 1), also passt es nicht.
Da es keine weiteren 6tupel aktuell zum prüfen gibt, erschaffen wir ein neues leeres 6tupel und fügen dort die zahl ein.

neue 6tupel liste:
{(1,2,3,4,5,6),(1,2,7,0,0,0)}

und so gehts weiter.


ich gleiche also zwangsläufig jedes 3tupel mit jedem (vorhandenen) 6 tupel ab und falls möglich, füge in dieses das 3tupel ein.

diese 2 schritte, prüfen und falls möglich einfügen, hätte ich gerne in einer methode vereinigt.

wobei ich gerade am überlegen bin bzgl. des hinzufügens, ob ich nicht besser ein neues 6tupel bastle, das ich im wechsel mit den zahlen aus dem alten 6tupel und dem 3tupel fülle.
paralleler durchlauf oder wie das heißt.
habe es noch nciht erwähnt aber der einfahcheit halber will ich alle tupel stets aufsteigend sortiert halten.
sodass ich da mit parallelem durchlauf vermutlich alle zahlen abdecken könnte.


nur ein problem:
das neue, später zuzuweisende, tupel, erschaffe ich mit länge 6.
weil soll ja am ende auch wieder aus 6 zahlen bestehen.

wenn nun aber gegebenenfalls beim einfügen die 6 stellen übershcritten werden müssten, käme es zu einem error. was nicht so cool wäre.
darum wäre vorher die matheberehcnung, ob es rein mathematisch passen kann, trotzdem nötig.

wobei ich natürlich auch ganz hardcore versuchen kann, es mit try{} einfahc versuchen zu lassen und bei einem error shceitertt es halt.
aber das bringts mir ja auch nicht denn dann weiß ich gegebenenfalls nicht ob es eingefügt wurde oder nicht und würde es, im worst case, woanders nochmal einfügen.

wobei ja auch weiß gott was in dem try teil passieren kann, was womöglich nciht mal einen error triggertz aber trotzdem nicht erfolgreich das einfügt bzw. einfügen kann.

was meint ihr was da die sinnvollste variante ist.


mein problem ist halt auch dass ich rein für die matheprüfung vorab ja auch schon schleifenmässig rausfinden muss wie viele gmeeinsame zahlen es gibt, wie nviele 0stellen das 6tupel vorher hatte und so, also auch shcon ein paar mal durch das 6tupel durchlaufen muss.
und das selbe mehr oder minder beim eigentlichen einfügen dann nochmal muss. :-/


Hat da Jemand eine gute idee wie ich das möglichst sparsam und mit möglichst wenig zig mal durchlaufen der arrays hinkriege :-/
 
Auchg eins meiner vielen probleme:
Beim erzeugen der lsite an 3 tupel, die ich ja als int[][], also 2dimensionales array, schreibe, weiß ich ja gar nicht wie viele einträge es gibt.
also welche länge die erste dimension haben muss, was ich ja direkt beim erzeugen vom array shcon angeben muss :-/

wie löse ich das am besten?
 
Man kann ausrechnen wie groß der Array sein müsste, aber Arrays können nur INT32_MAX elemente haben, also spätestens für 6-Tupel sind die eh zu klein. Ich würde da vielleicht einen Weg suchen, der ohne 13 Mrd Allocations auskommt, oder mir das Speichern aller Permutationen am besten gleich ganz sparen. Das Geheimnis heißt hier vermutlich "Mathematik"(mir ist immer noch nicht klar, warum du alle Permutationen speichern willst, das scheint mir eher eine recht simple Stochastikaufgabe zu sein) ;)
 
Man kann ausrechnen wie groß der Array sein müsste
Ich hab mir den Spaß mal gemacht ^^ Vorrausgesetzt, das Array wird tatsächlich mit int initialisiert, würden alle möglichen Kombinationen und Permutationen von 6-Tupeln mit Zahlen 1-49 (ohne doppelte Zahlen) ca. 75 GiB reine Datenmenge beanspruchen. Und selbst wenn die Reihenfolge keine Rolle spielen würde (d.h. ohne die Permutationen), wären es immer noch rund 107 MiB.

Rechnung:
\[ \underbrace{\frac{49!}{(49-6)!}}_{\text{Kombinationen und Permutationen}}\cdot\underbrace{\frac{64\,\text{bit}}{8\,\frac{\text{bit}}{\text{B}} \cdot 2^{30}\,\frac{\text{B}}{\text{GiB}}}}_{\text{Speichergröße von \textit{int} in GiB}} \approx 70.015\,\text{GiB} \]
\[ \underbrace{\frac{49!}{(49-6)! \: 6!}}_{\text{Kombinationen ohne Permutationen}}\cdot\underbrace{\frac{64\,\text{bit}}{8\,\frac{\text{bit}}{\text{B}} \cdot 2^{20}\,\frac{\text{B}}{\text{MiB}}}}_{\text{Speichergröße von \textit{int} in MiB}} \approx 106.69\,\text{MiB} \]
 
Ja das ist noch eine sehr günstige Abschätzung nach unten, in der Praxis hat die JVM da ja noch einen Haufen Overhead dabei.
Ist jedenfalls, eigentlich nicht praktikabel und sicher der falsche Weg. Brute-Force ist i.A. eine echt dumme Idee, auf die man wirklich nur zurückfallen sollte, wenn man beweisen kann, dass es keinen besseren Weg gibt oder die Datenmengen sicher so klein sind, dass es keine Rolle spielt. ArrayList etc. sind für solche Datenmengen ohnehin komplett raus, da viel viel viel zu langsam.
 
Hehe, deswegen meinte ich auch "reine Datenmenge" ^^ Ist auf jeden Fall eine blöde Idee, das Zeug zu speichern und du hast absolut recht, die Aufgabe sieht sehr danach aus, als könne man sie einfacher lösen.

@bernd Was ist denn deine eigentliche Aufgabe, wofür brauchst du die Tupel?
 
Also ich weiß nicht wie ich die Arrays mergen soll ohne sie zu speichern irgendwie...

Naja, ich will mir halt ein Lottosystem basteln mit so wenig nötigen Tippreihen wie möglich, mit dem man beim Spielen garantiert ein mal mind. 3 Richtige hat.

Dazu will ich halt ganz simpel alle möglichen 3tupel nehmen und die der reihe nach in ein anfangs leeres lottosystem einfügen.
Laut der Mathe von irgendwem wird das um die 170 lottoreihen ergeben.
Aber ich hätte mir durch "proof by construction" einfach mal selber gerne die Lottoreihen gebastelt und, indem ich sie einfach zähle, geguckt wie viele Reihen es sind.

Dazu muss ich am Ende vom lied eine Liste von 3Tupel nach bestimmten Regeln in eine Liste von 6 Tupel zwängen, je weniger, desto besser.

So als Beispiel:
Ein banales wenngleich ineffizietentes Vorgehen ist es ja, je zwei 3tupel in eine 6erzelle zu packen.
braucht man, nehmen wir jetzt mal an es gäbe insgesamt 10000 3Tupel, entsprechend 10000/2=5000 Tippreihen.

Hat aber 2 Nachteile:
a) Es kommen Zahlen in einer Zelle doppelt vor und
b) wenn man die Dopplungen streicht, sind leere Stellen in vielen Tippfeldern.
Sodass man locker 2 Tippreihen kombinieren kann ohne dass die kombinierte Zelle mehr als 6 Zahlen hat.

Gibt also viel optimierungsmöglichkeiten, um die Zellenzahl runterzubringen.

Um da halbwegs effizient zu sein, will ich bereits beim Einfügen eines 3 tupels gucken, dass ich es so platzsparend wie nur logisch unterbringe.

haben wir also bspw. die 3tupel (1,2,3) und (2,3,7),
dann könnte man die primitiv zusammenfügen zu (1,2,3,2,3,7)
problem halt mit doppelten zahlen und co.

man kann aber auch berücksichtigen dass manche zahlen in beiden tupeln vorkommen, die man ja nur einmal und nicht zweimal einfügen muss.

Also anfangs leeres tupel: (0,0,0,0,0,0)
dann das erste 3tupel eingefügt:
(1,2,3,0,0,0)
dann das zweite 3tupel, aber halt intelligent, eingefügt:
(1,2,3,7,0 0)
was sehen wir dabei?
die 3tupel (1,2,3) und (2,3,7) werden sowohl von
(1,2,3,2,3,7)
als auch von
(1,2,3,7,0 0)
erfasst, allerdings hat letzteres keine doppelten zahlej und dadurch 2 plätze noch frei.

ausserdem hätte es ja nachdem passieren können, wenn wir pech haben, dass wir bspw.
(1,2,3,4,0,0) haben und wollen (2,4,9) einfügen.

gingen wir nahc der dummen variante, würden wir denken "Yo, 2 leere stellen, aber 3 zahlen, passt nicht mehr rein" und würden fälschlicherweise eine neue reihe anfangen obwohl es unnötig ist.
beim intelligenten verfahren merken wir sofort dass nur die 9 die einzige, neu hinzukommende zahl ist.
und da 1 neue zahl<2 leere stellen, past es locker rein UND es ist sogar noch eine stelle frei!


ergo, will ich hier nicht erst ineffizient arbeiten und später mühsam nachkorrigieren sondern von anfang an gleich schlau einfügen.
damit erst gar nicht diemenge an lottoreihen nicht erst künstlich aufgeblasen ist bevor man sie zig mal optimieren muss.

jedenfalls will ich, intelligent aber, eine unmenge an 3tupeln in ein raster aus 6tupeln einfügen.
je weniger 6tupel für das ganze nötig sind, umso besser :)


Und ja, bei der mathe bzgl. "wie viele 3tupel gibt es insgesamt" kam ich auf eine zu vereinfachende dreifachsumme, die einfach keinen spaß macht bzw. wo ich mich immer verrechne.
irgendwer behauptee mal, es gäbe um die 18000 3tupel oder so :-/
 
Und ja, bei der mathe bzgl. "wie viele 3tupel gibt es insgesamt" kam ich auf eine zu vereinfachende dreifachsumme, die einfach keinen spaß macht bzw. wo ich mich immer verrechne.
irgendwer behauptee mal, es gäbe um die 18000 3tupel oder so :-/
Was für eine Dreifachsumme?
Ich hab das jetzt so verstanden: Ein 3-Tupel bei dir besteht aus 3 Zahlen, die zwischen 1 und 49 liegen können. Jetzt darf dabei aber keine Zahl doppelt vorkommen und du möchtest wissen, wie viele Möglichkeiten es jetzt dafür gibt, richtig?
In dem Fall kannst du dir immer noch zwei Fälle überlegen:
  1. Die Reihenfolge der Zahlen spielt eine Rolle, d.h. (3, 35, 12) wäre nicht das gleiche 3-Tupel wie (12, 3, 35) und demnach eine weitere Möglichkeit.
  2. Die Reihenfolge der Zahlen spielt keine Rolle, d.h. (3, 35, 12) wäre das gleiche 3-Tupel wie (12, 3, 35).
Bei beidem kann man die Anzahl der möglichen 3-Tupel recht einfach ausrechnen:
  1. Fall: \[ 49\cdot 48\cdot 47 = \frac{49!}{(49-3)!} = 110544 \]
  2. Fall: \[ \frac{49\cdot 48\cdot 47}{3\cdot 2\cdot 1} = \frac{49!}{(49-3)!\:3!} = \binom{49}{3} = 18424 \]
Dazu will ich halt ganz simpel alle möglichen 3tupel nehmen und die der reihe nach in ein anfangs leeres lottosystem einfügen.
Laut der Mathe von irgendwem wird das um die 170 lottoreihen ergeben.
Ich verstehe nicht so ganz, was dieses "Lottosystem" machen soll. Wenn du die möglichen 3-Tupel so abstrus einfügen willst, wie du beschrieben hast, wirst du jedenfalls bei Weitem nicht alle möglichen 6-er Tipps bekommen. Vermutlich nichtmal 'nen Bruchteil; wie viel das wäre, hatte ich ja weiter oben schon ausgerechnet.
Naja, ich will mir halt ein Lottosystem basteln mit so wenig nötigen Tippreihen wie möglich, mit dem man beim Spielen garantiert ein mal mind. 3 Richtige hat.
Wie soll ich das denn verstehen? Beim Lotto gibt man doch nur einen Tipp ab und kein Array an Möglichkeiten... Wie willst du da mindestens 3 Richtige erreichen?
 
Zuletzt bearbeitet:
Naja, wenn ich die Formel für die Sahcen nicht kennen würde, dann müsste ich eben eine Dreifachsumme lösen wie
Summe von i=1 bis 49 von(
Summe von j=i+1 bis 49 von(
Summe von k=j+1 bis 49 von(
1
)))

oder so (bei den genauen Summengrenzen bin ich mir etwas unsicher).
Was sich halt, mit viel mathe und hin und her rechnen, irgendwann zu einer einzigen Zahl ausrechnen lässt.
Jene Zahl gibt mir dann eben an wie viele Tripel sozusagen es gibt, wo die Lottozahlen ohne zurücklegen und ohne reihenfolge gezogen wurden.
eben wie beim richtigen Lotto, nur dass hier 3 statt 6 zahlen gezogen werden.


diese lsite an tripeln mache ich mir dazu damit ich mit der mir eine, möglichst kurze, Liste an 6tupeln aufbauen kann, die dann letztlich den lottoreihen entspricht die man später tippen würde.
Durch geschicktes einfügen ist ja die Anzahl an nötigen 6tupeln nicht gleich anzahl an 3tupeln/2, sondern viel kleiner.
irgendwo las ich was von 176 tippfeldern um alle nur irgendwie möglcihen 3tupel abzudecken.

wozu unbedingt alle tripel einfügen?

Damit, wenn man später gleichzeitig(!) diese 176 oder so lottofelder spielt, mindestens ein gewinn der gewinnklasse 3 richtige dabei ist.

dass der gewinn da weit unter dem einsatz liegt, ist schon klar.

mir gehts mehr drum wie man das programmiert.

weil wenn ich das hier hinkriege, dann lässt es sich leicht für jedes problem der form "system für lotto a aus b zahlen, damit garantiert einmal c richtige getroffen werden" verallgemeirn und anpassen.



"Wie soll ich das denn verstehen? Beim Lotto gibt man doch nur einen Tipp ab und kein Array an Möglichkeiten... Wie willst du da mindestens 3 Richtige erreichen?"

Wie du schon erkennst, will ich ja nicht nur ein tippfeld spielen sondern ne bestimmte menge an tippfeldern auf einmal.
insofern man die ganzen zu tippenden 6tupel sinnvoll wählt, kann man da effizienter vorgehen.
cih meien, es gibt vermutlich um die 18000 tripel.
würde man ganz stumpf einfach jedes tripel einmal verwenden, bräuchte man zwangsläufig 18000/2=90000 tippfelder.
einfach weil zwei mal 3 zahlen in ein tippfeld passen beim otto 6 aus 49.

aber das ist ineffizient und mit klugem auswählen der zu tippenden zahlen kann man es, so behauptet es das internet, auf nur 176 tipps runterbringen.

und da ja jedes tippfeld geld ksotet, mal von der gebühr pro schein abgesehen, macht das an nötigem einsatz schon einen Unterschied! :)

profitable ist das Alles so oder so nicht. aber wenn ich so viel tippreihen auf einmal spielen will dass ich, wozu auch immer, garantiert mind. einmal 3 Richtige habe,
dann lässt sich der nötige einsatz mit so einem system gut drücken.

legt man es hingegen auf mind. 4 richtige oder so irgendwas an, braucht man wiederum ein anderes system.
und ja, superzahl und zusatzzahl habe ich voll ignoriert und mal so getan, als ginge es wirklich nur um 6 zahlen aus 49 :)
 
Wenn ich so länger drüber nachdeke, muss ich ja gar nciht alle 18000 3tupel gleichzeitig gespeichert haben, es reicht ja wenn ich sie einmal kurz erzeuge, direkt einfüge und danach wieder vergesse. also eigentlich nur immer ein einziges tripel im speicher behalte mit dem ich gerade arbeite.

die 6 tupel liste werde ich hingegen so behalten müssen, immerhin brauche ich ja am ende die fertige liste zur weiterverwendung.

Damit dürfte das ganze gar nicht mal so speicheraufwendig werden, ich meine ein 3tupel und halt die lsite an 6tupeln,w as ich zeitgleich speichern muss.

Ich sehe eine Hfffnung am Ende des Tunnels! O_O

Da kann ich ja doch ganz simpel arraylists verwenden! :O

und spare mir so manche for shcleife zum iterieren über die 3tupel lsite da mir ja ein einziges 3tupel zu einem zeitpunkt ausreicht!
 
Zurück
Oben Unten