Zu viele "wenn" - Aussagen?
Folgende code funktioniert wie ich es brauche, aber es ist hässlich, übertrieben oder eine Reihe anderer Dinge. Habe ich mir angeschaut Formeln und versucht zu schreiben, ein paar Lösungen, aber ich am Ende mit einer ähnlichen Menge von Aussagen.
Ist es eine Art mathematische Formel, die profitieren würden mich in diesem Fall oder 16, wenn Aussagen akzeptabel?
Den code zu erklären, es ist eine Art simultan-rundenbasiertes Spiel.. zwei Spieler haben vier action-buttons und die Ergebnisse kommen aus einem array (0-3), aber die Variablen 'ein' & 'zwei' zugeordnet werden können, nichts, wenn das hilft. Das Ergebnis ist, 0 = weder gewinnen, 1 = p1 gewinnt, 2 = p2 gewinnt, 3 = beide zu gewinnen.
public int fightMath(int one, int two) {
if(one == 0 && two == 0) { result = 0; }
else if(one == 0 && two == 1) { result = 0; }
else if(one == 0 && two == 2) { result = 1; }
else if(one == 0 && two == 3) { result = 2; }
else if(one == 1 && two == 0) { result = 0; }
else if(one == 1 && two == 1) { result = 0; }
else if(one == 1 && two == 2) { result = 2; }
else if(one == 1 && two == 3) { result = 1; }
else if(one == 2 && two == 0) { result = 2; }
else if(one == 2 && two == 1) { result = 1; }
else if(one == 2 && two == 2) { result = 3; }
else if(one == 2 && two == 3) { result = 3; }
else if(one == 3 && two == 0) { result = 1; }
else if(one == 3 && two == 1) { result = 2; }
else if(one == 3 && two == 2) { result = 3; }
else if(one == 3 && two == 3) { result = 3; }
return result;
}
InformationsquelleAutor der Frage TomFirth | 2014-03-19
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Sie nicht kommen mit einer Formel, die Sie verwenden können, ein Tisch für eine begrenzte Anzahl von Ergebnissen:
InformationsquelleAutor der Antwort laalto
Da Ihre Daten-set ist so klein, man kann alles komprimieren in 1 long integer und verwandeln Sie es in eine Formel
Mehr bitweise Variante:
Diese macht sich die Tatsache zu nutze, alles ist ein Vielfaches von 2
Die Herkunft der Magischen Konstante
Was kann ich sagen? Die Welt braucht Magie, manchmal die Möglichkeit, dass etwas fordert, für seine Schöpfung.
Die Essenz der Funktion, die OP löst das problem ist das eine map aus 2 zahlen (eins,zwei), domain {0,1,2,3} , Bereich {0,1,2,3}. Jede der Antworten hat sich so zu implementieren, dass Karte.
Auch, Sie sehen in einer Reihe von Antworten, eine Neuformulierung des Problems als eine Karte von 1 2-stellige base 4 Anzahl N(eins,zwei), wo man die Ziffer 1, zwei ist Ziffer 2 und N = 4*eins + zwei; N = {0,1,2,...,15} -- sechzehn verschiedene Werte, das ist wichtig. Die Ausgabe der Funktion ist eine 1-stellige base 4 Zahl {0,1,2,3} -- 4 verschiedene Werte, auch wichtig.
Nun, eine 1-stellige Basis-4-Zahl ausgedrückt werden kann als eine 2-stellige Basis-2 Zahl; {0,1,2,3} = {00,01,10,11}, und somit ist jede Ausgabe codiert werden kann mit nur 2 bits. Von oben, es gibt nur 16 verschiedene Ausgänge möglich, also 16*2 = 32 bit ist alles, was notwendig ist für die Kodierung der gesamten Karte; diese können alle passen in 1 integer.
Die Konstante M ist eine Kodierung der map m, wobei m(0) wird codiert, in den bits M[0:1], m(1) codiert, in den bits M[2:3] und m(n) codiert, in den bits M[n*2:n*2+1].
Alles, was bleibt, ist die Indizierung und die Rückgabe der Rechte Teil des Konstanten, in diesem Fall können Sie bei gedrückter Umschalttaste M rechts, 2*N-mal und die 2 am wenigsten signifikanten bits,, (M >> 2*N) & 0x3. Die Ausdrücke (<< 3) und (zwei << 1) sind nur die Multiplikation Dinge aus und stellt fest, dass 2*x = x << 1 und 8*x = x << 3.
InformationsquelleAutor der Antwort waTeim
Ich mag keinen der präsentierten Lösungen, außer für JAB ist. Keiner der anderen es einfach machen, den code zu Lesen und zu verstehen, was berechnet.
Hier, wie ich, würde dieser code zu schreiben-ich weiß nur, C#, Java nicht, aber Sie erhalten das Bild:
Jetzt ist es viel mehr klar, was berechnet hier: dies unterstreicht, dass wir-computing, die getroffen wird, durch das, was angreifen und für die Rückgabe der beiden Ergebnisse.
Allerdings könnte dies noch besser; das Boolean-array ist etwas undurchsichtig. Ich mag die Tabelle-lookup-Ansatz, aber ich wäre geneigt zu schreiben, es in einer Weise, die deutlich machte, was der beabsichtigten Spiel-Semantik wurden. Das heißt, anstatt "ein Angriff von null und eine Verteidigung ergibt keine Treffer", statt einen Weg finden, um den code deutlicher zu bedeuten "einen low-kick-Angriff und einem niedrigen block-Verteidigung ergibt sich kein Treffer". Den code spiegeln die business-Logik des Spiels.
InformationsquelleAutor der Antwort Eric Lippert
Können Sie erstellen, die matrix enthält die Ergebnisse
Wenn Sie möchten, um Wert, den Sie verwenden
InformationsquelleAutor der Antwort djm.im
Andere Leute haben auch schon vorgeschlagen, meine ursprüngliche Idee, die matrix-Methode, sondern darüber hinaus zur Festigung der if-Anweisungen können Sie vermeiden, einige von dem, was Sie haben, dafür zu sorgen, dass Argumente geliefert werden, die in dem erwarteten Bereich und mithilfe von in-place gibt (einige coding-standards, die ich gesehen habe durchzusetzen, one-point-of-Abfahrt für Funktionen, aber ich habe festgestellt, dass mehrere Rücksendungen sind sehr nützlich für die Vermeidung von Pfeil Codierung und mit der Prävalenz von Ausnahmen in Java es gibt nicht viel Punkt in streng Durchsetzung dieser Regel jedenfalls als jede uncaught exception geworfen werden, innerhalb der Methode ist ein möglicher Punkt, der Ausgang sowieso). Verschachtelung switch-Anweisungen ist eine Möglichkeit, aber für den kleinen Bereich der Werte, die Sie überprüft haben, hier finde ich die if-Anweisungen werden kompakter und voraussichtlich nicht zu viel von einem performance-Unterschied, vor allem, wenn Ihr Programm ist rundenbasiert statt in Echtzeit.
Diese nicht am Ende wird weniger lesbar, als es sonst aufgrund der Unregelmäßigkeit der Teile der input->Ergebnis-mapping. Ich bevorzuge den matrix-Stil statt, die aufgrund Ihrer Einfachheit und wie können Sie die matrix sinnvoll visuell (aber das ist zum Teil beeinflusst durch meine Erinnerungen von Karnaugh maps):
Update: Angesichts Ihrer erwähnen zu blockieren/schlagen, hier ist eine weitere Radikale änderung der Funktion, die nutzt propertied/Attribut-holding aufgezählten Arten für die Eingaben und das Ergebnis und ändert auch das Ergebnis ein wenig zu Konto für die Sperrung, sollte das Ergebnis in eine besser lesbare Funktion.
Sie haben nicht einmal um die Funktion zu ändern, selbst wenn Sie hinzufügen möchten, Blöcke/Angriffe, mehr Höhen, nur die enums; zusätzliche Arten von Bewegungen wird wahrscheinlich erfordern eine änderung der Funktion, wenn. Auch,
EnumSet
s könnte besser erweiterbar als die Verwendung von extra enums als Eigenschaften der wichtigsten enum, z.B.EnumSet<Move> attacks = EnumSet.of(Move.ATTACK_HIGH, Move.ATTACK_LOW, ...);
und dannattacks.contains(move)
eher alsmove.type == MoveType.ATTACK
allerdings mitEnumSet
s wahrscheinlich etwas langsamer sein als die direkte equals prüft.Für den Fall, wo ein erfolgreicher block Ergebnisse in einen Zähler, können Sie ersetzen Sie
if (one.height == two.height) return LandedHit.NEITHER;
mitAuch, ersetzen einige der
if
Aussagen mit der Nutzung der ternäre operator (boolean_expression ? result_if_true : result_if_false
) könnte der code kompakter (zum Beispiel, der code im vorherigen block werden würdereturn one.isAttack() ? LandedHit.PLAYER_TWO : LandedHit.PLAYER_ONE;
), aber kann dazu führen, dass hart-zu-Lesen oneliners also ich würde nicht empfehlen es für komplexere Verzweigung.InformationsquelleAutor der Antwort JAB
Warum nicht ein array?
Werde ich von vorne beginnen. Ich sehe eine Muster, die Werte von 0 bis 3, und Sie will fangen Sie alle möglichen Werte. Dies ist Ihre Tabelle:
wenn wir uns diese gleichen Tabelle, binäre wir die folgenden Ergebnisse:
Nun vielleicht haben Sie schon sehen, einige Muster, aber wenn ich verbinden mit dem Wert eins und zwei sehe ich, dass Sie über alle Werte 0000, 0001, 0010,..... 1110 und 1111. Nun wollen wir kombinieren mit dem Wert eins und zwei, um einen einzelnen 4-bit-integer.
Wenn wir übersetzen diese wieder in dezimale Werte, die wir sehen, ein sehr gut möglich, Werte-array, wo die eins und zwei kombiniert werden könnten, dient als index:
Anschließend wird das array
{0, 0, 1, 2, 0, 0, 2, 1, 2, 1, 3, 3, 2, 1, 3, 3}
wo es der index ist einfach eins und zwei kombiniert.Ich bin kein Java-Programmierer, aber Sie loswerden können alle if-Anweisungen und schreiben Sie einfach nieder, wie so etwas wie dieses:
Ich weiß nicht, ob ein bitshift um 2 schneller ist als die Multiplikation. Aber es könnte einen Versuch Wert sein.
InformationsquelleAutor der Antwort dj bazzie wazzie
Nutzt diese ein wenig bitmagic (Sie tun es bereits durch Aufnahme von zwei bits von Informationen (niedrig/hoch & Angriff/block) in einem einzigen integer):
ich habe es nicht benutzen, nur schrieb es hier, bitte prüfen.Die Idee sicher funktioniert.EDIT: ist Es jetzt getestet, die für jede Eingabe, funktioniert gut.
Oder sollte ich schlage vor, trennen Sie die zwei bits von Informationen in separate Variablen?
Code meist basierend auf dem bit-Operationen, wie dies oben ist in der Regel wirklich schwer zu pflegen.
InformationsquelleAutor der Antwort elias
Um ganz ehrlich zu sein, jeder hat Ihren eigenen Stil-code. Ich würde nicht gedacht haben, wäre die Leistung betroffenen zu viel. Wenn Sie das besser verstehen, als mit einer switch-case-version, und fahren Sie dann mit dieser.
Könnte man nest ifs , also möglicherweise gab es eine leichte performance-Steigerung für Ihren letzten, wenn Prüfungen als wäre es nicht gegangen, durch so viele if-Anweisungen. Aber in Ihrem Kontext eines grundlegenden java-Kurs wird es wahrscheinlich nicht nutzen.
So, anstatt...
Würden Sie tun...
Und einfach formatieren Sie es wie Sie möchten.
Nicht der code besser Aussehen, aber möglicherweise beschleunigt Sie ein wenig, glaube ich.
InformationsquelleAutor der Antwort Joe Harper
Lassen Sie uns sehen, was wir wissen
1: Ihre Antworten sind symmetrisch für P1 (Spieler eins) und P2 (Spieler zwei). Dies macht Sinn für ein Kampf-Spiel, aber ist auch etwas, das Sie nutzen können, um verbessern Sie Ihre Logik.
2: 3 beats beats 2 0 schlägt 1 Schläge 3. Die einzigen Fälle, die nicht unter diese Fälle sind Kombinationen von 0 vs 1 und 2 vs 3. Mit anderen Worten-der einzigartige Sieg-Tabelle sieht wie folgt aus: 0 schlägt 2, 1 Schläge 3, 2 Schläge 1, 3 schlägt 0.
3: 0/1 gehen gegeneinander, dann gibt es eine durch Hitless ziehen, aber wenn 2/3 gehen gegen jede dann beide Treffer
Erste, lasst uns bauen Sie ein one-way-Funktion, die uns erzählen, wenn wir gewonnen:
Können wir dann verwenden Sie diese Funktion zum erstellen der final-Ergebnis:
Während dies ist wohl komplexer und wahrscheinlich langsamer als die lookup-Tabelle angeboten, in vielen Antworten ich glaube, es ist eine hervorragende Methode, weil es tatsächlich kapselt die Logik des Codes und beschreibt es jedem, der das Lesen Ihres Codes. Ich denke, dies macht es zu einem besseren Umsetzung.
(Es ist schon eine Weile her, ich habe alle Java-also entschuldigt, wenn die syntax aus, hoffentlich ist es trotzdem verständlich, wenn ich habe es ein wenig falsch)
Durch die Art und Weise, 0-3 klar bedeuten etwas; Sie sind nicht beliebige Werte, so dass es helfen würde, Sie zu benennen.
InformationsquelleAutor der Antwort Jack Aidley
Ich hoffe, ich verstehe die Logik richtig. Wie wäre es mit etwas wie:
Überprüfung one-hit-high oder one-hit-low ist nicht blockiert, und das gleiche gilt für Spieler zwei.
Edit: Algorithmus wurde nicht vollständig verstanden, "hit" vergeben, wenn die Blockierung, die mir nicht bewusst (Danke elias):
InformationsquelleAutor der Antwort Chris
Ich habe keine Erfahrung mit Java, so könnte es einige Tippfehler. Bitte betrachten Sie das code-pseudo-code.
Dann würde ich mit einem einfachen Schalter. Für, die, Sie müssten eine einzelne Zahl Evaluierung. Jedoch, für diesen Fall, da
0 <= one < 4 <= 9
und0 <= two < 4 <= 9
können wir konvertieren die beiden ints zu einem einfachen int durch Multiplikationone
durch 10 und addierentwo
. Verwenden Sie dann einen Schalter in die sich daraus ergebende Zahl wie diese:Gibt es noch eine kurze Methode, die ich möchte nur darauf hinweisen, wie eine theoretische code. Aber ich würde es nicht verwenden, weil es einige zusätzliche Komplexität, die Sie normalerweise nicht wollen, zu beschäftigen. Die zusätzliche Komplexität kommt aus der base 4denn das zählen wird 0, 1, 2, 3, 10, 11, 12, 13, 20, ...
Wirklich nur als zusätzlicher Hinweis, falls ich etwas fehlt von Java. In PHP würde ich das tun:
InformationsquelleAutor der Antwort Francisco Presencia
Da Sie lieber verschachtelte
if
Bedingungen , hier ist ein anderer Weg.Beachten Sie, dass es nicht die
result
Mitglied und es ändert sich nicht, egal welcher Zustand.InformationsquelleAutor der Antwort Nick Dandoulakis
Versuchen Sie es mit switch-Gehäuse...
Werfen Sie einen Blick hier oder hier für mehr info über es
Können Sie hinzufügen mehrere Bedingungen(nicht gleichzeitig) und auch haben eine Standard-optionwo keine anderen Fälle zufrieden gewesen.
PS: Nur wenn eine Bedingung ist, um zufrieden zu sein..
Wenn 2 Bedingungen gleichzeitig auftreten.. ich glaube nicht, dass Schalter verwendet werden kann.
Aber reduzieren Sie Ihren code hier ein.
Java switch-Anweisung in mehreren Fällen
InformationsquelleAutor der Antwort Nevin Madhukar K
Ist die erste Sache, die mir einfiel, war im wesentlichen die gleiche Antwort gegeben von Francisco Presencia, aber etwas optimiert:
Könnte man noch weiter optimieren, indem der Letzte Fall (für 3) den default-Fall:
Der Vorteil dieser Methode ist, dass es einfacher ist, zu sehen, welche Werte für
one
undtwo
entsprechen, die Werte zurückgeben, als einige der anderen vorgeschlagenen Methoden.InformationsquelleAutor der Antwort David R Tribble
InformationsquelleAutor der Antwort Dawood ibn Kareem
Können Sie einen switch case statt mutiple
if
Auch zu erwähnen, dass da Sie haben zwei Variablen, dann haben Sie die Zusammenführung der beiden Variablen, um Sie in Schalter
Überprüfen Sie diese Java switch-Anweisung um zwei Variablen?
InformationsquelleAutor der Antwort Rahul Tripathi
Wie ich zeichnen Sie eine Tabelle zwischen ein/zwei und das Ergebnis ist, ich sehe eine Muster,
Den oben abschneiden würde unten mindestens 3 if-Anweisungen. Ich sehe nicht ein festes Muster, noch bin ich in der Lage zu Lesen viel aus dem code - aber wenn eine solche Logik abgeleitet werden kann, wäre es cut nach unten eine Reihe von if-Anweisungen.
Hoffe, das hilft.
InformationsquelleAutor der Antwort AnonNihcas
Einen guten Punkt zu definieren, die Regeln als text, können Sie leichter abzuleiten, die richtige Formel dann. Dies ist ein Auszug aus laalto ist schön-array-Darstellung:
Und hier gehen wir mit einigen Allgemeinen Bemerkungen, aber Sie beschreiben soll, Sie in der Regel Begriffe:
Natürlich könnten Sie crunch hinunter zu weniger code, aber es ist generell eine gute Idee, um zu verstehen, was Sie den code eher als die Suche nach einer kompakten Lösung.
Einige Erklärung auf die komplizierte p1/p2 trifft, wäre toll, sieht interessant aus!
InformationsquelleAutor der Antwort Marcellus
Die kürzeste und noch lesbar Lösung:
oder noch kürzer:
Enthält keine "Magische" Zahl 😉
Hoffe, es hilft.
InformationsquelleAutor der Antwort P.W.
static int val(int i, int u){
int q = (i & 1) ^ (u & 1);
return ((i >> 1) << (1 ^ q))|((u >> 1) << q);
}
InformationsquelleAutor der Antwort user1837841
Ich persönlich mag die Kaskade ternäre Operatoren:
Aber in Ihrem Fall, die Sie verwenden können:
Oder, Sie können feststellen, ein Muster in bits:
So können Sie Magie verwenden:
InformationsquelleAutor der Antwort Kirill Gamazkov
Hier ist eine ziemlich prägnante version, ähnlich JAB Antwort. Dieser nutzt eine Karte, um zu speichern, welche Bewegungen triumph über andere.
Beispiel:
Drucke:
InformationsquelleAutor der Antwort Duncan Jones
Ich würde eine Karte, entweder HashMap oder TreeMap
Besonders, wenn der Parameter nicht auf die form
0 <= X < N
Wie eine Reihe von zufälligen positiven ganzen zahlen ..
Code
InformationsquelleAutor der Antwort Khaled.K
Dank @Joe Harper als landete ich mit einer variation seiner Antwort. Zu schlank nach unten weiter als 2 Ergebnisse pro 4 waren die gleichen, die ich abgespeckt es weiter nach unten.
Ich zurück kommen können, um diese an einem gewissen Punkt, sollte es aber keine größeren Widerstand verursacht durch mehrere
if
-Aussagen, dann behalte ich das jetzt. Ich werde in der Tabelle, matrix-und switch-Anweisung-Lösungen weiter.InformationsquelleAutor der Antwort TomFirth
Hier ist ein Vorschlag, wie dies Aussehen könnte, aber die Nutzung eines ints hier ist immer noch eine Art von hässlich:
Schöner wäre es natürlich, verwenden Sie einen strukturierten Datentyp für die Eingabe und die Ausgabe. Die Eingabe hat eigentlich zwei Felder: die position und den Typ (block oder Angriff). Die Ausgabe hat auch zwei Felder: player1Wins und player2Wins. Die Kodierung dieser in einem einzigen ganzzahligen macht es schwieriger, den code zu Lesen.
Leider ist Java nicht sehr gut an, um diese Arten von Daten-Typen.
InformationsquelleAutor der Antwort peq
Stattdessen so etwas tun
InformationsquelleAutor der Antwort onkar