2009-04-28 9 views
2

Ich habe etwas über meine Codierung bemerkt, die etwas undefiniert ist. Angenommen, wir haben ein zweidimensionales Array, eine Matrix oder eine Tabelle, und wir prüfen, ob eine Eigenschaft für jede Zeile oder geschachtelte Dimension zutrifft.Wahr bis widerlegt oder falsch bis bewiesen?

Angenommen, ich habe ein boolesches Flag, das verwendet werden soll, um zu überprüfen, ob eine Eigenschaft wahr oder falsch ist. Meine Optionen sind:

  1. Initialisieren Sie es auf True und überprüfen Sie jede Zelle, bis bewiesen falsch. Dieser gibt ihm einen falschen Namen, bis der Code vollständig ausgeführt wird.
  2. Beginnen Sie mit false und überprüfen Sie jede Zeile, bis sie sich als wahr erwiesen hat. Nur wenn alle Zeilen wahr sind, sind die Daten korrekt. Was ist der sauberste Weg, dies ohne einen Zähler zu tun?

Ich habe immer 1 getan, ohne zu denken, aber heute habe ich mich gefragt. Was ist mit 2?

+0

Danke für die Antworten. Ich habe es geschafft, den gleichen Effekt nur nach Verwendung zusätzlicher boolescher Werte zu erhalten. Es gab keine einfache Überprüfung. Ich habe unterschätzt, wie anders es wäre, weil es nur ein Wert ist, der sich ändert. Das Problem mit der Einstellung der Eigenschaft auf True ist, dass die nächsten Elemente es plötzlich widerlegen können. Ich nehme an, Sie könnten es als propertyUnproven = true bezeichnen und dann auf false setzen, wenn es ungültig ist. Was ist, wenn die Schleife selbst die richtige Antwort erfordert, bevor das Flag auf false gesetzt wird? –

Antwort

3

Sie beide tatsächlich auf die gleiche Sache und da Sie sagen "überprüfen, ob eine Eigenschaft für jede Zeile oder verschachtelte Dimension gilt", glaube ich, die erste Methode ist leichter zu lesen und vielleicht etwas schneller.

Sie sollten nicht versuchen, den Wert des Flags zu lesen, bis der Code trotzdem vollständig ausgeführt wird, da die Prüfung nicht abgeschlossen ist. Wenn Sie asynchronen Code ausführen, sollten Sie sich davor schützen, auf den Wert zuzugreifen, während dieser instabil ist.

Beide Methoden "geben einen falschen Namen", bis der Code ausgeführt wird. 1 gibt falsche Positive und 2 gibt falsche Negative. Ich bin nicht sicher, was Sie vermeiden möchten, indem Sie das sagen - wenn Sie den "korrekten" Wert erhalten können, bevor Sie Ihren Code vollständig ausführen, haben Sie Ihren Code nicht an erster Stelle ausgeführt.


Wie jeder ohne einen Zähler implementieren (wenn Sie die entsprechende enumerator->next Schleife Syntax keine foreach Syntax in Ihrer Sprache haben, verwenden):

1:

bool flag = true; 

foreach(item in array) 
{ 
    if(!check(item)) 
    { 
     flag = false; 
     break; 
    } 
} 

2 :

bool flag = false; 
foreach(item in array) 
{ 
    if(!check(item)) 
    { 
     break; 
    } 
    else if(item.IsLast()) 
    { 
     flag = true; 
    } 
} 
+0

Vielen Dank, ich mag diese Antwort. Wie sauber findest du es persönlich? –

0

Machen Sie den Namen der Eigenschaft etwas wie isThisTrue. Dann wird mit "Ja" oder "Nein" geantwortet, aber es ist immer sinnvoll.

In Ruby und Scheme können Sie ein Fragezeichen im Namen verwenden: isThisTrue?. In vielen anderen Sprachen gibt es eine Konvention, p "p" für "Prädikat" auf den Namen - null-p für einen Test zu setzen, der wahr oder falsch in LISP zurückgibt.

12

Hängt davon ab, was man zuerst aus der Schleife ausgibt, IMHO.

Zum Beispiel würde ich bei einer OR-Situation auf false setzen, und sobald Sie einen TRUE erhalten, geben Sie das Ergebnis zurück, andernfalls geben Sie den Standard zurück, wenn die Schleife durchfällt.

Für eine UND-Situation würde ich das Gegenteil tun.

0

Ich stimme Will Hartung.

Wenn Sie sich Sorgen um (1) machen, dann wählen Sie einfach einen besseren Namen für Ihre Boolean. IsNotSomething statt IsSomething.

+0

Ist das aber ein klarer Name? (Aus irgendeinem Grund hat Stackoverflow gerade drei Kommentarboxen hinzugefügt) –

1

Persönlich werfe ich nur die ganze Schleife in eine etwas wiederverwendbare Methode/Funktion mit dem Namen isPropertyAlwaysTrue (Eigenschaft, Array [] []) und es direkt ein false zurückgeben, wenn es findet, dass es einen Fall findet, wo es nicht wahr ist.

Die Umkehrung der Logik, übrigens, bringt Sie nicht schneller da raus. Wenn Sie beispielsweise den ersten Nicht-Wahr-Fall haben wollen, wird die Angabe von areAnyFalse oder areAllTrue eine invertierte Ausgabe haben, aber genau die gleichen Fälle müssen getestet werden.

Dies ist auch der Fall mit areAnyTrue und areAllFalse - verschiedene Wörter für den gleichen Algorithmus (zurückgeben, sobald Sie eine wahre finden).

Sie können AreAnyFalse nicht mit AreAnyTrue vergleichen, weil sie auf eine völlig andere Situation testen.

2

Gehen Sie mit der ersten Option. Ein Algorithmus hat immer Vorbedingungen, Nachbedingungen und Invarianten. Wenn Ihre Invariante "bool x ist wahr, wenn alle Zeilen von 0-currentN eine positive Eigenschaft haben" ist, dann ist alles in Ordnung.

Machen Sie Ihren Algorithmus nicht komplexer, nur um den vollen Programmstatus pro Zeileniteration gültig zu machen. Refaktorieren Sie die Methode, extrahieren Sie sie und machen Sie sie mit Ihrer Sprachmechanik (Java: synchronized) "atomar".