Schleife hängt sich auf. Fehlersuche erfolglos. Was ist da los?
Griever
- javascript
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>
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/)
In einigen Minuten werde ich halt die zeilenumgebrochene Version dieses Codes ausgeben.
PS: Ich habe keinen AMD-Prozessor!
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.
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
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)
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/)
Hi.
Wenn du genau schaust, wirst du merken, dass ich aus dem String mit alpha = alpha.split("") ein Array mache.
MFG
Griever