Griever: Schleife hängt sich auf. Fehlersuche erfolglos. Was ist da los?

Hi.

Ich habe mir eine kleine Spielerei (NUR für IE) erlaubt. Dadurch lernt man am besten über irgendwas. Aus Versuch und Fehlschlag.
Nun ja. Aber ein Problem kriege ich einfach nicht gelöst.

Ich habe hier folgende Variablen:

  
var alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";alpha = alpha.split("");  
var Chemikalien = new Array();  

Ist natürlich billig gemacht und der eine oder andere hat noch ein paar verbesserungsvorschläge. Aber mal drüberweggesehen ...

Ich habe mir eine Schleife (zumindestens 3 verschachtelte For-Schleifen) erstellt, welche mir danach alle Kombinationen einer aus 3 Buchstaben bestehenden Zeichenfolge in die Variable Chemikalien schreibt. So steht es bei mir drin:

  
 for(var i = 0;i<alpha.length;i++)  
 {  
  for(var j = 0;j<alpha.length;j++)  
  {  
   for(var k = 0;k<alpha.length;k++)  
   {  
    Chemikalien[Chemikalien.length]=alpha[i]+alpha[j]+alpha[k]  
   }  
  }  
 }  

Doch egal wie ich es versuche anzustellen. Diese Schleife bleibt immer stehen.

Ich habe herausgefunden, dass es genau 175756 Kombinationen gibt. Aber ich frage mich, warum der IE etwa 600000 Codes innerhalbt von 2 Minuten erstellt, jedoch bei diesen 17k nach 15 minuten abbricht.

Kann mir vielleicht jemand einen Rat geben?

Hier mal das komplette Script (Sehr umfangreich! Es sind einige kleine Fehler drin, aber das ist erstmal unwichtig):

  
<body>  
<script language="JavaScript">  

~~~~~~javascript
  
<!--  
// Allchemiescript via JavaScript  
var AnzahlChemikalien = 0  
var alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";alpha = alpha.split("");  
var menge = 50  
var Chemikalien = new Array();  
if(AnzahlChemikalien > 0)  
{  
 for(var i = 0;i<AnzahlChemikalien;i++){Chemikalien[i] = alpha[Math.round(Math.random()*(alpha.length-1))]+alpha[Math.round(Math.random()*(alpha.length-1))]+alpha[Math.round(Math.random()*(alpha.length-1))]}  
}  
else  
{  
  
  
  
 // Um diese Schleife gehts!  
  
  
  
  
 for(var i = 0;i<alpha.length;i++)  
 {  
  for(var j = 0;j<alpha.length;j++)  
  {  
   for(var k = 0;k<alpha.length;k++)  
   {  
    Chemikalien[Chemikalien.length]=alpha[i]+alpha[j]+alpha[k]  
   }  
  }  
 }  
  
  
  
  
  
  
  
}  
  
var SaveReg = null,Seconda = 0  
document.write("<span id='Reagenz'></span>")  
var Substanzenarray = new Array()  
var rekursivdurchschnitt = 0  
function Start_Mix(REGGLASS) {  
  
if(SaveReg == null){  
SaveReg = REGGLASS;  
Seconda = REGGLASS;  
rekursivdurchschnitt = REGGLASS.Aktuell/REGGLASS.Substanzen.length  
for(var i in Seconda.Substanzen)  
{  
  var rrt = 0;  
  for(var j = 0;j<Chemikalien.length;j++){  
    if(Chemikalien[j]==Seconda.Substanzen[i]){  
      rrt=j;  
      break;  
    }  
  }  
  Substanzenarray[Substanzenarray.length]=j  
}  
REGGLASS.Aktuell = 0;  
REGGLASS.Substanzen = new Array()  
}  
else  
{  
SaveReg = REGGLASS;  
for(var i in Seconda.Substanzen)  
{  
  var rrt = 0;  
  for(var j = 0;j<Chemikalien.length;j++){if(Chemikalien[j]==Seconda.Substanzen[i]){rrt=j;break;}}Substanzenarray[Substanzenarray.length]=j};  
  for(var i in SaveReg.Substanzen){  
  var rrt = 0;  
  for(var j = 0;j<Chemikalien.length;j++)  {  
  if(Chemikalien[j]==SaveReg.Substanzen[i])    {  
  rrt=j;  
  break;    }  }  
  Substanzenarray[Substanzenarray.length]=j  
  }  
  REGGLASS.Substanzen = new Array();  
  REGGLASS.Aktuell = 0;  
  for(var i in Substanzenarray){  
  if(REGGLASS.Kanngenutztwerden == true){  
  REGGLASS.AddSubstanz(Substanzenarray[i],rekursivdurchschnitt)}else{break;}}Seconda.Aktuell = 0;Seconda.Substanzen = new Array();SaveReg = null;Seconda = null;Substanzenarray = new Array()}return REGGLASS}  
function REAGGLASS(MaximaleFuellhoeheInTics) {this.Substanzen = new Array();this.Maximum = MaximaleFuellhoeheInTics;this.Aktuell = 0;this.Kanngenutztwerden=true;this.AddSubstanz = function(Substanz,Menge) {if(this.Kanngenutztwerden == true){if(this.Aktuell - Number("-"+Menge) > this.Maximum){alert("Das Reagenzglas ist explodiert!");this.Aktuell=0;this.Substanzen = new Array();this.Maximum = 0;this.Kanngenutztwerden = false}else{  if(Menge >= 1)  {    this.Aktuell += Number(Menge);    this.Substanzen[this.Substanzen.length] = Chemikalien[Substanz];  }}alleAnzeigen()}else{alert("Das Reagenzglas ist zerstört und kann nicht verwendet werden!")}}}  
function AddReagenzglas(AnzahlGlaeser,MaximaleFuellhoeheInTics){for(var i = 1;i<=AnzahlGlaeser;i++){eval("this.Reagenzglas_"+i+" = new REAGGLASS("+MaximaleFuellhoeheInTics+")")}}  
function alleAnzeigen() {document.getElementById("Reagenz").innerHTML = "";for(var i in Reagenzglaeser){var farbe = (Reagenzglaeser[i].Kanngenutztwerden == true)?"#009F00":"#BF0000";  
if(SaveReg == null){document.getElementById("Reagenz").innerHTML += "<div style=\"color:"+farbe+";\">"+i.replace("_"," ")+" ("+Reagenzglaeser[i].Aktuell+" / "+Reagenzglaeser[i].Maximum+" || "+((Reagenzglaeser[i].Substanzen.join(", ")=="")?((Reagenzglaeser[i].Kanngenutztwerden==true)?"Leer":"Kaputt"):Reagenzglaeser[i].Substanzen)+") <a href=\"javascript:Reagenzglaeser."+i+".AddSubstanz(document.getElementById('DSUB').value,menge)\">[Substanz zufügen]</a>|<a href=\"javascript:void(0)\" onClick=\"Reagenzglaeser."+i+" = Start_Mix(Reagenzglaeser."+i+");alleAnzeigen()\">[Mischen ...]</a></div>"}else{document.getElementById("Reagenz").innerHTML += "<div style=\"color:"+farbe+";\">"+i.replace("_"," ")+" ("+Reagenzglaeser[i].Aktuell+" / "+Reagenzglaeser[i].Maximum+" || "+((Reagenzglaeser[i].Substanzen.join(", ")=="")?((Reagenzglaeser[i].Kanngenutztwerden==true)?"Leer":"Kaputt"):Reagenzglaeser[i].Substanzen)+") <a href=\"javascript:void(0)\" onClick=\"Reagenzglaeser."+i+" = Start_Mix(Reagenzglaeser."+i+");alleAnzeigen()\">[... mit diesem.]</a></div>"}}}  
var Mischung = new Array();  
var Reagenzglaeser = new AddReagenzglas(10,500);  
document.write("<select style=\"width:200px;\" size=1 id=\"DSUB\">")  
Chemikalien.sort()  
var Doppelte = 0  
for(var i in Chemikalien)  
{  
  var SuchWert = Chemikalien[i]  
  for(var j in Chemikalien)  
  {  
    if(Chemikalien[i] == Chemikalien[j])  
    {  
      Chemikalien.splice(j,j)  
      Doppelte++  
    }  
  }  
}  
  
function setMenge(x)  
{  
 menge=x  
}  
  
for(var i in Chemikalien){document.write("<option value="+i+">"+Chemikalien[i]+"</option>")}  
document.write("</select>")  
document.body.onload = alleAnzeigen  
-->  

~~~~~~html
  
</script></body>  

  1. for(var i = 0;i<alpha.length;i++)
    {
      for(var j = 0;j<alpha.length;j++)
      {
       for(var k = 0;k<alpha.length;k++)
       {
        Chemikalien[Chemikalien.length]=alpha[i]+alpha[j]+alpha[k]
       }
      }
    }

    
    >   
    > Doch egal wie ich es versuche anzustellen. Diese Schleife bleibt immer stehen.  
      
    Bei mir läuft die innerhalb von sekundenbruchteilen durch.  
      
    
    >   
    > Ich habe herausgefunden, dass es genau 175756 Kombinationen gibt. Aber ich frage mich, warum der IE etwa 600000 Codes innerhalbt von 2 Minuten erstellt, jedoch bei diesen 17k nach 15 minuten abbricht.  
      
    wenn ich mir mit alert die Länge ausgeben lasse kommt nur 17576 raus.  
      
      
    
    > Kann mir vielleicht jemand einen Rat geben?  
    >   
    > Hier mal das komplette Script (Sehr umfangreich! Es sind einige kleine Fehler drin, aber das ist erstmal unwichtig):  
      
    Ich kann dir nur einen Rat geben: ordentlichen Code schreiben, ich blick da nicht durch, das ist der Code des Grauens. Ich weiß nicht ob du durch die Vermeidung von Zeilenumbrüchen Bytes sparen willst, dass macht vielleicht Sinn wenn du noch einen 80286 Rechner mit 8MB hast.  
      
    Struppi.
    
    -- 
    [Javascript ist toll](http://javascript.jstruebig.de/)
    
    1. In einigen Minuten werde ich halt die zeilenumgebrochene Version dieses Codes ausgeben.

      PS: Ich habe keinen AMD-Prozessor!

      1. In einigen Minuten werde ich halt die zeilenumgebrochene Version dieses Codes ausgeben.

        Naja, ob's beeser wird weiß ich nicht, ich hab da evals gesehen.

        PS: Ich habe keinen AMD-Prozessor!

        Ein 80286'er ist ein Intel Prozessor (ein Vorläufer des Pentiums)

        Struppi.

        1. Re

          Ein 80286'er ist ein Intel Prozessor (ein Vorläufer des Pentiums)

          Das war ironisch gemeint. Mein CPU hat nicht allzu hohe Leistungen. Dass deiner das in bruchteilen schafft, ist mir klar. Meiner aber nicht. Wenn du das ganze Script mal im IE startest, wirst du es sehen ...

          Hier mal aufgeräumter Code:

            
          <body>  
          <script type="text/javascript">  
          
          ~~~~~~javascript
            
          <!--  
          // Allchemiescript via JavaScript  
          var AnzahlChemikalien = 799,alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";alpha = alpha.split("");  
          var menge = 50,Chemikalien = new Array();  
          // Abfragen, ob als Anzahl 0 oder niedriger eingegeben wurde. Wenn nein, gegebene Anzahl an Kombinationen erstellen.  
            
          if(AnzahlChemikalien > 0)  
          {  
           // Schleife zur zufallserstellung einer Kombination (später noch korrigiert)  
           for(var i = 0;i<AnzahlChemikalien;i++)  
           {  
            Chemikalien[i] = alpha[Math.round(Math.random()*(alpha.length-1))]+alpha[Math.round(Math.random()*(alpha.length-1))]+alpha[Math.round(Math.random()*(alpha.length-1))]  
           }  
          }  
          else  
          {  
           // Schleife zur erstellung sämtlicher Möglichkeiten.  
           for(var i = 0;i<alpha.length;i++)  
           {  
            for(var j = 0;j<alpha.length;j++)  
            {  
             for(var k = 0;k<alpha.length;k++)  
             {  
              Chemikalien[Chemikalien.length]=alpha[i]+alpha[j]+alpha[k]  
             }  
            }  
           }  
          }  
            
          // Interne Variablen  
          var SaveReg = null,Seconda = 0,Substanzenarray = new Array(),rekursivdurchschnitt = 0  
          // Ausgabeobjekt schreiben  
          document.write("<span id='Reagenz'></span>")  
            
          // 2 Reagenzgläser mischen-Funktion  
          function Start_Mix(REGGLASS)  
          {  
           if(SaveReg == null)  
           {  
            // Capturen der übergebenen Reagenzgläser in externe (außerhalb von der Funktion stehende) Variablen.  
            SaveReg = REGGLASS;  
            Seconda = REGGLASS;  
            // Durchschnitt berechnen ... (nach änderung sowieso überflüssig)  
            rekursivdurchschnitt = REGGLASS.Aktuell/REGGLASS.Substanzen.length  
            
            // Substanzen auszählen  
            for(var i in Seconda.Substanzen)  
            {  
             var rrt = 0;  
             // Chemikalienindex herausfinden.  
             for(var j = 0;j<Chemikalien.length;j++)  
             {  
              if(Chemikalien[j]==Seconda.Substanzen[i])  
              {  
               // Bei fund variable übergeben und schleife abbrechen.  
               rrt=j;  
               break;  
              }  
             }  
             // Substanznummer speichern  
             Substanzenarray[Substanzenarray.length]=j  
            }  
            // Leeren des Reagenzglases.  
            REGGLASS.Aktuell = 0;  
            REGGLASS.Substanzen = new Array()  
           }  
           else  
           {  
            // Wenn ein Reagenzglas gewählt wurde ...  
            // Übergebenen Wert speichern ...  
            SaveReg = REGGLASS;  
            
            // Substanzen herauslesen und in Chemikalienindex umwandeln  
            for(var i in Seconda.Substanzen)  
            {  
             var rrt = 0;  
             for(var j = 0;j<Chemikalien.length;j++)  
             {  
              if(Chemikalien[j]==Seconda.Substanzen[i])  
              {  
               rrt=j;  
               break;  
              }  
             }  
             // Der Liste hinzufügen.  
             Substanzenarray[Substanzenarray.length]=j  
            };  
            
            // Erneut ...  
            for(var i in SaveReg.Substanzen)  
            {  
             var rrt = 0;  
             for(var j = 0;j<Chemikalien.length;j++)  
             {  
              if(Chemikalien[j]==SaveReg.Substanzen[i])  
              {  
               rrt=j;  
               break;  
              }  
             }  
             Substanzenarray[Substanzenarray.length]=j  
            }  
            // Reagenzglas leeren.  
            REGGLASS.Substanzen = new Array();  
            REGGLASS.Aktuell = 0;  
            
            // Substanzen in Array schreiben und danach in das neue Reagenzglas geben  
            for(var i in Substanzenarray)  
            {  
             // Fragen, ob das Reagenzglas benutzbar ist  
             if(REGGLASS.Kanngenutztwerden == true)  
             {  
              // Substanz in das Reagenzglas geben.  
              REGGLASS.AddSubstanz(Substanzenarray[i],rekursivdurchschnitt)  
             }  
             else  
             {  
              // Abbrechen, falls das Glas nicht verwendbar ist.  
              break;  
             }  
            }  
            
            // Vorheriges Reagenzglas leeren  
            Seconda.Aktuell = 0;  
            Seconda.Substanzen = new Array();  
            // Variablen leeren  
            SaveReg = null;  
            Seconda = null;  
            Substanzenarray = new Array()  
           }  
           // Reagenzglas zurückgeben.  
           return REGGLASS  
          }  
            
          // Erstellen eines neuen Reagenzglases (PART 2)  
          function REAGGLASS(MaximaleFuellhoeheInTics)  
          {  
           // Substanzliste (ARRAY) erstellen.  
           this.Substanzen = new Array();  
           // Maximale Füllhöhe festlegen  
           this.Maximum = MaximaleFuellhoeheInTics;  
           // Aktuelle Füllhöhe festlegen  
           this.Aktuell = 0;  
           // Benutzbarkeit setzen.  
           this.Kanngenutztwerden=true;  
           // Funktion zur Substanzhinzufügung erstellen  
           this.AddSubstanz = function(Substanz,Menge)  
           {  
            // Abfragen, ob das Reagenzglas noch benutzbar ist  
            if(this.Kanngenutztwerden == true)  
            {  
             // Abfragen, ob die neue Menge über der Maximalmenge liegt  
             if(this.Aktuell - Number("-"+Menge) > this.Maximum)  
             {  
              // Fehlermeldung  
              alert("Das Reagenzglas ist explodiert!");  
              // Leeren des Reagenzglases  
              this.Aktuell=0;  
              this.Substanzen = new Array();  
              this.Maximum = 0;  
              // Unbenutzbar machen  
              this.Kanngenutztwerden = false  
             }  
             else  
             {  
              // Prüfen, ob Menge über 0 liegt  
              if(Menge >= 1)  
              {  
               // Menge zufügen zu aktueller Füllhöhe  
               this.Aktuell += Number(Menge);  
               // Substanz dem Reagenzglas zufügen  
               this.Substanzen[this.Substanzen.length] = Chemikalien[Substanz];  
              }  
             }  
             // Reagenzgläser neu anzeigen  
             alleAnzeigen()  
            }  
            else  
            {  
             // Fehlermeldung für zerstörtes Reagenzglas  
             alert("Das Reagenzglas ist zerstört und kann nicht verwendet werden!")  
            }  
           }  
          }  
            
          // Neue Reagenzgläser erstellen (PART 1)  
          function AddReagenzglas(AnzahlGlaeser,MaximaleFuellhoeheInTics)  
          {  
           // Schleife für mehrere Reagenzgläser  
           for(var i = 1;i<=AnzahlGlaeser;i++)  
           {  
            // Eval-Funktion für ansprechen auf dieses Reagenzglas  
            eval("this.Reagenzglas_"+i+" = new REAGGLASS("+MaximaleFuellhoeheInTics+")")  
           }  
          }  
            
          // Alle Reagenzgläser zeigen  
          function alleAnzeigen()  
          {  
           // Ausgabeobjekt leeren.  
           document.getElementById("Reagenz").innerHTML = "";  
           //Schleife für die Ausgabe  
           for(var i in Reagenzglaeser)  
           {  
            // farbe für "ganze" und "zerstörte" Reagenzgläser  
            var farbe = (Reagenzglaeser[i].Kanngenutztwerden == true)?"#009F00":"#BF0000";  
            // Prüfung, ob ein Mischvorgang eingeleitet wurde  
            if(SaveReg == null)  
            {  
             // Anzeigen der Standardoptionen (sind derzeit nur in einer Zeile)  
             document.getElementById("Reagenz").innerHTML += "<div style=\"color:"+farbe+";\">"+i.replace("_"," ")+" ("+Reagenzglaeser[i].Aktuell+" / "+Reagenzglaeser[i].Maximum+" || "+((Reagenzglaeser[i].Substanzen.join(", ")=="")?((Reagenzglaeser[i].Kanngenutztwerden==true)?"Leer":"Kaputt"):Reagenzglaeser[i].Substanzen)+") <a href=\"javascript:Reagenzglaeser."+i+".AddSubstanz(document.getElementById('DSUB').value,menge)\">[Substanz zufügen]</a>|<a href=\"javascript:void(0)\" onClick=\"Reagenzglaeser."+i+" = Start_Mix(Reagenzglaeser."+i+");alleAnzeigen()\">[Mischen ...]</a></div>"  
            }  
            else  
            {  
             // Anzeigen der Zweitoption für das Mischen 2er Reagenzgläser (sind derzeit nur in einer Zeile)  
             document.getElementById("Reagenz").innerHTML += "<div style=\"color:"+farbe+";\">"+i.replace("_"," ")+" ("+Reagenzglaeser[i].Aktuell+" / "+Reagenzglaeser[i].Maximum+" || "+((Reagenzglaeser[i].Substanzen.join(", ")=="")?((Reagenzglaeser[i].Kanngenutztwerden==true)?"Leer":"Kaputt"):Reagenzglaeser[i].Substanzen)+") <a href=\"javascript:void(0)\" onClick=\"Reagenzglaeser."+i+" = Start_Mix(Reagenzglaeser."+i+");alleAnzeigen()\">[... mit diesem.]</a></div>"  
            }  
           }  
          }  
            
          // Andere Variablen.  
          var Mischung = new Array();  
            
          // Initiieren der Reagenzgläser in die Variable Reagenzglaeser  
          var Reagenzglaeser = new AddReagenzglas(10,500);  
            
          // Startobjekt für eine Drop-Down-Liste ID = "DSUB"  
          document.write("<select style=\"width:200px;\" size=1 id=\"DSUB\">")  
            
          // Sortieren der Chemikalien, die zur Verfügung stehen.  
          Chemikalien.sort()  
            
          // Variable für das Zählen der Doppelten Chemikalien  
          var Doppelte = 0  
            
          // Schleife zum entfernen von Doppelten  
          for(var i in Chemikalien)  
          {  
           // Suchwert setzen  
           var SuchWert = Chemikalien[i]  
           // Chemikalien erneut durchgehen und alle Doppelten entfernen.  
           for(var j in Chemikalien)  
           {  
            // Fragen, ob das aktuelle Objekt nicht das suchobjekt ist.  
            if(j == i)  
            {  
             // Überprüfen, ob die 2 Chemikalien identisch sind  
             if(Chemikalien[i] == Chemikalien[j])  
             {  
              // Entfernen des doppelten Eintrags  
              Chemikalien.splice(j,j)  
              // Zähle erhöhen.  
              Doppelte++  
             }  
            }  
           }  
          }  
            
          // Schleife für die Listen-Elemente  
          for(var i in Chemikalien)  
          {  
           // Schreiben einer Option für die DDL (Drop-Down-Liste) ...  
           document.write("<option value="+i+">"+Chemikalien[i]+"</option>")  
          }  
          // Abschließen der DDL  
          document.write("</select>")  
          // Startevent festlegen  
          document.body.onload = alleAnzeigen  
          -->  
          
          ~~~~~~html
            
          </script>  
          </body>  
          
          

          Wenn du Fehler findest, scheue dich nicht, mich damit zu konfrontieren.

          MFG
          Griever

  2. Hello out there!

    Chemikalien[Chemikalien.length]=alpha[i]+alpha[j]+alpha[k]

    Hab gerade keinen 6er; aber der 5er IE kann nicht mit alpha[i] auf das i-te Zeichen eines Strings zugreifen: ~~~javascript var foo = "A";
    alert(foo[0]);

      
      
    
    > Doch egal wie ich es versuche anzustellen. Diese Schleife bleibt immer stehen.  
      
    Sicher, dass es bei dir diese Schleife ist? Lass doch mal vor und nach der Schleife eine Meldung ausgeben.  
      
      
    
    > Ich habe herausgefunden, dass es genau 175756 Kombinationen gibt.  
      
    Tippfehler: es sind 26³ = 17576.  
      
    See ya up the road,  
    Gunnar
    
    -- 
    “Remember, in the end, nobody wins unless everybody wins.” (Bruce Springsteen)
    
    1. Hab gerade keinen 6er; aber der 5er IE kann nicht mit alpha[i] auf das i-te Zeichen eines Strings zugreifen: ~~~javascript

      var foo = "A";

      alert(foo[0]);

        
      Griever programmiert nur für den IE 6.  
        
      Struppi.
      
      -- 
      [Javascript ist toll](http://javascript.jstruebig.de/)
      
      1. Hi.

        Wenn du genau schaust, wirst du merken, dass ich aus dem String mit alpha = alpha.split("") ein Array mache.

        MFG
        Griever