Frage

Bei der Überprüfung, habe ich manchmal diese Art von Schleife auftreten:

i = begin
while ( i != end ) {    
   // ... do stuff
   if ( i == end-1 (the one-but-last element) ) {
      ... do other stuff
   }
   increment i
}

Dann stelle ich die Frage: würden Sie schreiben diese

i = begin
mid = ( end - begin ) / 2 // (the middle element)
while ( i != end ) {    
   // ... do stuff
   if ( i > mid ) {
      ... do other stuff
   }
   increment i
}

Meiner Meinung nach, schlägt dies die Absicht, eine Schleife zu schreiben: Sie Schleife, weil es etwas gemeinsam für jedes der Elemente durchgeführt werden. Mit diesem Konstrukt, für einige der Elemente, tun Sie etwas anderes. Also, ich schließen, müssen Sie eine separate Schleife für diese Elemente:

i = begin
mid = ( end - begin ) / 2 //(the middle element)
while ( i != mid ) {    
   // ... do stuff
   increment i
}

while ( i != end ) {
   // ... do stuff
   // ... do other stuff
   increment i
}

Jetzt habe ich sogar eine Frage auf SO, wie man schreiben die if-Klausel auf eine nette Art ... Und ich habe traurig. etwas nicht in Ordnung ist hier

Bin ich falsch? Wenn ja, was ist so gut über den Schleifenkörper mit besonderen Fällen unübersichtlich, die Sie bewusst im Voraus sind, zum Zeitpunkt Codierung?

War es hilfreich?

Lösung

@xtofl,

Ich bin mit Ihrem Anliegen.

Million Mal traf ich ähnliches Problem.

So oder Entwickler fügt eine spezielle Behandlung für die erste oder letzte Element.

In den meisten Fällen lohnt es sich, nur Schleife von StartIdx + 1 oder endIdx - 1 Element oder sogar eine lange Schleife in mehrere kürzere Schleifen aufgeteilt.

In sehr seltenen Fällen ist es nicht möglich ist, Schleife aufzuspalten.

Meiner Meinung nach ungewöhnlich Dinge sollten, wenn möglich außerhalb der Schleife behandelt werden.

Andere Tipps

Ich glaube nicht, diese Frage nach dem Prinzip beantwortet werden (zum Beispiel „in einer Schleife, jedes Element gleich behandeln“). Stattdessen können Sie auf zwei Faktoren schauen, um zu bewerten, ob eine Implementierung gut oder schlecht ist:

  1. Runtime Effektivität - macht der kompilierte Code schnell laufen, oder wäre es schneller es anders tun
  2. Code-Wartbarkeit - Ist es einfach (für einen anderen Entwickler) zu verstehen, was hier geschieht?

Wenn es schneller ist und der Code ist besser lesbar, indem sie alles in einer Schleife zu tun, tut es auf diese Weise. Wenn es langsamer und weniger lesbar ist, tun Sie es einen anderen Weg.

Wenn es schneller und weniger lesbar ist, oder langsamer, aber besser lesbar, herauszufinden, welche der Faktoren zählt mehr in Ihrem speziellen Fall, und dann entscheiden, wie eine Schleife (oder nicht Schleife).

Ich weiß, ich habe gesehen, wenn die Menschen versucht, Elemente eines Arrays in eine durch Kommata getrennte Zeichenfolge zu verbinden:

for(i=0;i<elements.size;i++) {
   if (i>0) {
     string += ','
   }
   string += elements[i]
}

Sie haben entweder, dass, wenn Klausel drin, oder Sie haben die Zeichenfolge + = Zeile am Ende wieder zu duplizieren.

Die offensichtliche Lösung ist in diesem Fall

string = elements.join(',')

Aber die Join-Methode hat die gleiche Schleife intern. Und es ist nicht immer eine Methode zu tun, was Sie wollen.

Ich kam zu der Erkenntnis, dass, wenn ich besondere Fälle in einem for-Schleife setzen, ich normalerweise bin für mein eigenes Wohl zu klug zu sein.

Im letzten Schnipsel Sie auf dem Laufenden, Sie Code wiederholen für // .... tun Sachen.

Es ist sinnvoll zu halten zwei Schleifen, wenn Sie ganz anderen Satz von Operationen auf einem anderen Satz von Indizes haben.

i = begin
mid = ( end - begin ) / 2 //(the middle element)
while ( i != mid ) {    
   // ... do stuff
   increment i
}

while ( i != end ) {
   // ... do other stuff
   increment i
}

Dies ist der Fall nicht zu sein, würden Sie noch eine einzige Schleife behalten wollen. Aber Tatsache bleibt, dass Sie nach wie vor (Ende - beginnen) speichern / 2 Anzahl der Vergleiche. So läuft es nach unten, ob Sie Ihren Code ordentlich aussehen oder Sie einige CPU-Zyklen zu speichern. Anruf bei Ihnen.

Ich glaube, Sie haben es ganz genagelt. Die meisten Menschen fallen in die Falle einschließlich bedingte Verzweigungen in Schleifen, wenn sie sie draußen tun können. Was einfach ist schneller

Zum Beispiel:

if(items == null)
    return null;

StringBuilder result = new StringBuilder();
if(items.Length != 0)
{
    result.Append(items[0]); // Special case outside loop.
    for(int i = 1; i < items.Length; i++) // Note: we start at element one.
    {
        result.Append(";");
        result.Append(items[i]);
    }
}
return result.ToString();

Und der mittlere Fall, dass Sie beschrieben ist einfach nur böse . Stellen Sie sich vor, wenn dieser Code wächst und muss in verschiedene Methoden Refactoring werden.

Wenn Sie XML parsen Schleifen sollte so einfach und präzise wie möglich gehalten werden.

Ich glaube, Sie haben Recht über die Schleife gleich mit allen Elementen zu beschäftigen gemeint ist. Leider manchmal gibt es spezielle Fälle obwohl und diese behandelt werden sollten innerhalb der Schleife über, wenn Anweisungen erstellen.

Wenn es gibt viele Spezialfälle obwohl Sie wahrscheinlich über kommt mit irgendeiner Art und Weise mit den zwei unterschiedlichen Gruppen von Elementen in separaten Konstrukten umgehen denken sollen.

Ich ziehe es einfach, das Element aus der Schleife ausschließen und gibt eine gesonderte Behandlung außerhalb der Schleife

Für zB: Lässt den Fall von EOF betrachten

i = begin
while ( i != end -1 ) {    
   // ... do stuff for element from begn to second last element
   increment i
}

if(given_array(end -1) != ''){
   // do stuff for the EOF element in the array
}

Natürlich, Spezial-Gehäuse Dinge in einer Schleife, die herausgezogen werden kann, ist dumm. Ich würde nicht die do_stuff duplizieren entweder obwohl; Ich entweder würde es in einer Funktion oder in einem Makro so dass ich copy-paste-Code nicht.

Eine andere Sache, die ich zu sehen, Hass ist die für-Fall-Muster :

for (i=0; i<5; i++)
{
  switch(i)
  {
    case 0:
      // something
      break;
    case 1:
      // something else
      break;
    // etc...
  }
}

Ich habe dies in echtem Code zu sehen.

Was man besser abschneidet?

Wenn die Anzahl der Elemente ist sehr groß, dann würde ich immer einmal Schleife, vor allem, wenn Sie ausführen wollen einig Betrieb auf jedem Punkt. Die Kosten für die bedingte Auswertung ist wahrscheinlich geringer als zweimal Looping.

Oops, natürlich Sie Looping nicht zweimal ... In diesem Fall zwei Schleifen zu bevorzugen sind. Allerdings behaupte ich, dass die primäre Überlegung sollte die Leistung sein. Es gibt keine Notwendigkeit, die bedingt in der Schleife (N-mal) entstehen, wenn Sie die Arbeit durch eine einfache Manipulation der Schleife Grenzen partitionieren (einmal).

Der Sonderfall sollte außerhalb der Schleife durchgeführt werden, wenn es nur einmal durchgeführt werden.

Allerdings kann es ein Index oder eine andere Variable sein (e), die innerhalb der Schleife nur einfacher zu halten sind aufgrund Scoping. Es gibt auch einen kontextuellen Grund für das Halten alle Operationen auf der Datenstruktur zusammen in der Regelstruktur sein kann, obwohl ich denke, das ist ein schwaches Argument für sich allein.

Es ist nur über sie nach Bedarf und Bequemlichkeit verwenden. Es ist als solche nicht erwähnt Elemente gleich zu behandeln und es ist sicherlich nicht schaden, die Eigenschaften Clubbing, die Sprache zur Verfügung stellt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top