# Array: Doppelte Charakteren löschen - Ein Lösungsversuch



## timriddance (30. Okt 2009)

Hallo zusammen, 

Ich habe folgende Aufgabe: Erstelle eine Methode, die ein char[] nimmt, doppelte Werte erkennt und ein anderes char[] zurückliefert, dass nur aus eindeutigen Werten besteht. Es dürfen keine zusätzlichen Klassen oder Techniken wie Generics benutzt werden.

Ich habe die Methode folgendermassen implementiert, ich hoffe, man kann den Kommentaren einigermassen folgen:


```
/**
	 * Removes duplicate characters from an array of characters. 
	 * The resulting array will consist of unique values only.
	 * @param in
	 * @return
	 */
	public static char[] removeDuplicates(char[] in){
		char[] out;
		boolean[] isDouble = new boolean[in.length];
		int counter = in.length;
		
		// iterate through in, set isDouble true for duplicate values
		for (int i = 0; i < in.length; i++) {
			if(!isDouble[i]){
				for (int j = i + 1; j < in.length; j++) {
					if(!isDouble[j]){
						if(in[i] == in[j]){
							isDouble[j] = true;
							counter--;
						} 
					}
				}
			}
		}
		// assertion: for every duplicate value in[k], isDouble[k] = true
		// assertion: counter equals the size of the array with only unique values
		
		// compute out[]
		out = new char[counter];

		boolean[] temp = new boolean[in.length];
		
		// since out and in won't have the same size, only add unique values from in to out
		for (int i = 0; i < out.length; i++) {
			int j = i;
			boolean breakThis = false;
			while(j < in.length && !breakThis){
				if(!isDouble[j] && !temp[j]){
					out[i] = in[j];
					breakThis = true;  // breaks the while loop, so that out[i] is not overwritten by 
									   // following unique in[j]
					temp[j] = true;	   // if true, assignment is skipped even when in[j] is a unique value;
									   // this avoids that one unique value is assigned to both out[i] and out[i+1]
				}
				j++;
			}
		}
		return out;
	}
```


Der Algorithmus funktioniert. Übergebe ich z.B. {'h','a','l','l','o'}, erhalte ich {'h','a','l','o'}.

Nun, ich werde das Gefühl nicht los, dass der Algorithmus a) unschön / unlesbar ist und b) ineffizient. In der zweiten For-Schleife im unteren Teil kam ich nicht umhin, ein weiteres Array boolean[] temp zu verwenden. Zuerst wollte ich es ohne dies tun, aber mir kam einfach nicht in den Sinn, wie ich verhindern konnte, dass wenn z.B. 

in =  {'h','a','l','l','o'} 
und somit
isDouble = {false, false, false, true, false} 
ist, 
das resultiertende Array out = {'h','a','l','l'} war, weil jedesmal i = j gesetzt wird.

Wer jetzt noch weiss, um was es geht - hut ab! 
Ausserdem wird z.B. die 1. Schleife, falls sich der erste wert von allen nachfolgenden unterscheidet, mindestens n*n ausgeführt, und im schlechtesten fall noch viel mehr. (n = in.length)

Ich bin noch nicht so erfahren mit effizientem, schönen Programmieren und hoffe ihr könnt mir helfen.

Lieber Gruss


----------



## Spacerat (30. Okt 2009)

Hmmm...
Dann werd' ich mal den Finduh kalifaken...
Aber was ich nicht verstehe ist, wieso versuchst du es nicht mal so?
	
	
	
	





```
public static char[] removeDuplicates(char fromChars) {
  StringBuilder tmp = new StringBuilder(String.valueOf(fromChars));
  for(int i = 0; i < tmp.length() - 1; i++) {
    for(int j = i + 1; j < tmp.length(); j++ {
      if(tmp.charAt(i) == tmp.charAt(j)) {
        tmp.deleteCharAt(j);
        --j;
      }
    }
  }
  return tmp.toString().toCharArray();
}
```


----------



## maki (30. Okt 2009)

Spacerat hat gesagt.:


> Hmmm...
> Dann werd' ich mal den Finduh kalifaken...
> Aber was ich nicht verstehe ist, wieso versuchst du es nicht mal so?
> 
> ...


Was wäre dann mit

```
{'h','a','l','o','l'}
```
?


----------



## timriddance (30. Okt 2009)

> Es dürfen keine zusätzlichen Klassen oder Techniken wie Generics benutzt werden.


 - _My Humble Self_


----------



## Spacerat (30. Okt 2009)

maki hat gesagt.:


> Was wäre dann mit
> 
> ```
> {'h','a','l','o','l'}
> ...


Ja... hab's schon gemerkt und verbessert... war wohl zu spät. aber so wies jetzt dasteht sollte es gehen. Scheinbar reicht das aber nicht.


----------



## timriddance (30. Okt 2009)

Nichts gegen deine Antwort, danke dir auch dafür, aber Ziel dieser Aufgabe ist es wirklich, allein mittels primitiver Datentypen zu programmieren.


----------



## Spacerat (30. Okt 2009)

Na was solls...
Der Ansatz mit den geschachtelten Schleifen steht jedenfalls:
	
	
	
	





```
public static char[] removeDuplicates(char[] fromChars) {
  for(int i = 0; i < fromChars.length - 1; i++) {
    for(int j = i + 1; j < fromChars.length; j++ {
      if(fromChars[i] == fromChars[j]) {
        fromChars = moveOneUp(fromChars, j);
        --j;
      }
    }
  }
  return fromChars;
}
```
dazu kommt dann noch eine weitere Methode:
	
	
	
	





```
private static char[] moveOneUp(char[] fromChars, int index) {
  char[] rc = new char[fromChars.length - 1];
  for(int i = 0, j = i; i < fromChars.length - 1; i++, j++) {
    if(j == index) {
      ++j;
    }
    rc[i] = fromChars[j];
  }
  return rc;
}
```
Genehm so?
@Edit: Wenn man es noch Speicher sparend und GC freundlich haben will:
	
	
	
	





```
public static char[] removeDoubles(char[] fromChars) {
  fromChars = fromChars.clone();
  int k = fromChars.length;
  for(int i = 0; i < k - 1; i++) {
    for(int j = i + 1; j < k; j++) {
      if(fromChars[i] == fromChars[j]) {
        moveOneUp(fromChars, j);
        --j;
        --k;
      }
    }
  }
  char[] rc = new char[k];
  for(int i = 0; i < k; i++) {
    rc[i] = fromChars[i];
  }
  return rc;
}

private static void moveOneUp(char[] fromChars, int index) {
  for(int i = 0, j = i; i < fromChars.length - 1; i++, j++) {
    if(j == index) {
      ++j;
    }
    fromChars[i] = fromChars[j];
  }
}
```
Im Gegensatz zum Vorhergehenden, werden hier nicht mehr als nur zwei Arrays neu erstellt.


----------



## Gast2 (31. Okt 2009)

[DUKE]es ist spät[/DUKE]


----------



## faetzminator (31. Okt 2009)

Wenn man nun zusätzliche Klassen verwenden würde, bringe ich einen Einzeiler hin, wenn auch leider nur ohne prmitiven Typen:

```
public static Character[] doIt(Character[] inp) {
	return new HashSet<Character>(Arrays.asList(inp)).toArray(new Character[0]);
}
```


----------



## timriddance (31. Okt 2009)

Danke für den Vorschlag, Spacerat!


----------



## Landei (31. Okt 2009)

```
private static char[] removeDuplicates(char[] array) {
        char[] copy = new char[array.length];
        for(int i = 0; i < array.length; i++) {
            copy[i] = array[i];
        }
        for(int j = array.length-1; j >= 1; j--) {
            for(int i = 0; i < j; i++) {
                if(copy[i] > copy[i+1]) {
                    char temp = copy[i];
                    copy[i] = copy[i+1];
                    copy[i+1] = temp;
                }
            }
        }
        int k = array.length;
        for(int i = 1; i < k; i++) {
           while(copy[i] == copy[i-1]) {
               for(int j = i; j < k-1; j++) {
                   copy[j] = copy[j+1];
               }
               k--;
           }
        }
        char[] result = new char[k];
        for(int i = 0; i < k; i++) {
            result[i] = copy[i];
        }
        return result;
    }
```


----------



## timriddance (31. Okt 2009)

Das sieht mir jetzt auf den Blick noch etwas komplizierter aus als meins, aber danke trotzdem.. werds noch durchgehen.


----------



## Landei (31. Okt 2009)

Eigentlich nicht:
- Array kopieren (damit das Original-Array erhalten bleibt)
- Kopie sortieren (Bubble Sort)
- bei allen Duplikaten von hinten her nachrücken, dabei Länge mitberechnen
- in ein entsprechend kürzeres Array kopieren

Wären Hilfsfunktionen wie Arrays.sort oder arrayCopy erlaubt, wäre das Ganze nicht mal halb so lang


----------



## Spacerat (31. Okt 2009)

@Landei: Und ich dachte schon, ich hätte übertrieben... BTW, wieso sortierst du das Array? War doch nicht Teil der Aufgabe?
@TS: Sollte an meinen Vorschlägen noch was am [c]clone()[/c] ausgesetzt werden, setze dafür einfach Landei's Zeilen ein, in denen er das Array kopiert. Kommt aufs selbe raus.


----------



## timriddance (31. Okt 2009)

Eure Vorschläge sind sicher auch eine gute Möglichkeit, das Problem zu lösen. Mich würde aber auch noch interessieren, ob ihr etwas an meinem zu kritisieren habt. Lesbarkeit (mal angenommen ich hätte keine Kommentare gesetzt), Effizienz?


----------



## ttplayer (31. Okt 2009)

Sorry, dass ich dich auch noch mit meinem Vorschlag zumülle, aber ich musste ihn auch noch loswerden

```
public static char[] removeDuplicates(char[] in)
	{
        int length = 0;
    	boolean[] used = new boolean[256];
        for (int counter = 0; counter < in.length;counter++)
        {        	
        	if (used[(int)in[counter]]) in[counter] = ' ';	//wenn der Character schon mal benutzt wurde
        	else
        	{
        		length++;
        		used[(int)in[counter]] = true;	//bei used wird im Feld, das dem Ascii-Code des chars entspricht, true eingetragen
        	}
        }
        char[] out = new char[length];
        int outcounter = 0;
        for (char inchar : in)
        {
        	if (inchar != ' ') 
        	{
        		out[outcounter] = inchar;
        		outcounter++;
        	}
        }
        return out;
    }
```


----------



## Spacerat (31. Okt 2009)

ttplayer hat gesagt.:


> ...aber ich kann nur Code lesen, den ich selbst geschrieben hab


Den Umstand musst du ändern! Solche Aussagen tragen nachteilig zur Einschätzung deiner Programmiererfahrung bei.





ttplayer hat gesagt.:


> kann aber gut sein, dass mein Code ein bisschen langsam ist...


Und hier erkennt man den Erfahrungs-Level... Die Selbsteinschätzung scheitert...





ttplayer hat gesagt.:


> Ach: Soll das Ganze nur mit Kleinbuchstaben funktionieren oder auch mit Großen?


Erfahrene sehen sofort: Es soll mit Characktern jeglicher Art funktionieren.
@ttplayer: Nicht das ich dich mit diesem Flamen will... sind nur gut gemeinte Tipps. Wenn ich mir deinen Code so ansehe, fürchte ich, dass das Array irgendwann leer wird, weil [c]' '[/c] immer wieder als doppelter Charakter fesgestellt wird. Der Code dürfte deswegen nicht nur recht ineffizient sein, sondern er würde nicht mal funktionieren.
@TS: Hätte man an deinem Code nichts auszusetzen gehabt, hätte man dir keinen effizienteren geben müssen. Das bedeutet also: Ja, da ist etwas dran auszusetzen. Allerdings nicht an der Lesbarkeit, die ist in Ordnung. Schon allein die Tatsachen, dass du erstens ein boolean für jeden Charakter erstellst ([c]isDouble[]-Array[/c] sowie deine eigene Aussage über die Ausführung der Schleife ([c]n*n[/c]) lassen vermuten, das es was schnelleres gibt. Ist man auf Primitivtypen beschränkt, dürfte meine Speicher sparende, GC freundliche Implementation die effizienteste sein. Ist man es nicht, sei auf faetzminator's Einzeiler verwiesen (mit 'ner geringen Änderung: [c]new Character[inp.length][/c]).


----------



## ttplayer (31. Okt 2009)

OK ich habs verbessert... und der Fehler war nicht der, dass er doppelte ' ' erkannt hätte, weil das Array wird erst geändert, nachdem er gesucht hat... der Fehler war, dass ich length falsch verwendet hab.


----------



## timriddance (31. Okt 2009)

Ok, danke. Das mit dem boolean array war ein Hint aus dem Lehrbuch, aus dem ich die Aufgabe habe. Aber ihr habt mir ja gezeigt, wies ohne ginge.
Was heisst denn eigentlich GC-freundlich?


----------



## ttplayer (31. Okt 2009)

also ich weiß bloß, dass gc eine Zeichnung bei SWT ist, aber sonst...??


----------



## eRaaaa (31. Okt 2009)

Garbage Collection ?


----------



## Spacerat (31. Okt 2009)

@eRaaaa: Genau.
GC freundlich ist, wenn man instanzierte und nicht mehr verwendete Objekte wiederverwendet, statt eine neu zu instanzieren und die alte Instanz dem GC überlässt. Das geht mit allen Objekten, die nicht Immutable sind.


----------



## timriddance (1. Nov 2009)

Ok, ich weiss zumindest was Immutable ist. Garbage Collection habe ich auch schon gehört, besonders in Bezug zu PHP5 OOP. Bei PHP ist es doch so, dass Objekte in den Kübel kommen, sobald das Skript zu Ende kompiliert/übersetzt wurde. Wie siehts bei Java aus?


----------



## Spacerat (1. Nov 2009)

Der GC ist solange die Runtime (JRE) läuft aktiv (in Java und afaik in PHP auch). Er durchsucht hin und wieder den für die Runtime zugewiesenen Speicher nach nicht mehr verwendeten Referenzen, also nach Referenzen die zu keinem Eintrag in der Variablentabelle passen. Hin und wieder bedeutet dabei, abhängig von der Belegung des Speichers in gewissen Zeitabständen, auf jeden Fall aber bevor ein OutOfMemoryError (oder wars 'ne RT-Exception?) geworfen wird. GC freundlich programmiert man, wenn man in Schleifen wann immer es geht Objekte "recycled" statt neu instanziert. Merke: Nicht mehr verwendete Referenzen belegen weiterhin Speicher und zwar solange, bis der GC merkt, das sie nicht mehr verwendet werden und deren Speicher freigeben kann.


----------



## hdi (1. Nov 2009)

Der GC läuft immer mal wieder über den Heap sowie andere Speicher-Bereiche wie z.B. den String Constant Pool. Dabei wird jedes Objekt zerstört (Der Speicher wird freigegeben), das nicht mehr referenziert wird. Sprich das vom Quellcode nicht mehr angesprochen werden kann.

Bsp:


```
SomeObject o = new SomeObject(); // o = 0xA4F13 (zB)
o = new SomeObject(); // o = 0xD91C
```

Das erste Objekt wird nun nicht mehr referenziert, d.h. es gibt keine Variable deren Wert die Speicheradresse dieses Objektes ist. (o wurde überschrieben).
Und somit wirst du das Objekt auch sicherlich nicht mehr verwenden (können), also wird es der GC demnächst zerstören.


----------



## Spacerat (1. Nov 2009)

hdi hat gesagt.:


> Sprich das vom Quellcode nicht mehr angesprochen werden kann.


Äh... Bin wirklich kein Erbsenzähler, aber du meinst sicher Bytecode statt Quellcode? Quellcode wird ja nicht ausgeführt.


----------



## hdi (1. Nov 2009)

Ähhh... 
Also vllt meinen wir das gleiche, vllt brauch ich auch Nachhilfe. Also Bytecode ist ja eigentlich das gleiche wie Quellcode, nur eben nicht in Java sondern in 1ern und 0ern, oder? Ich hab das bisher so verstanden: Sobald ich innerhalb des Quellcodes keinen Namen mehr habe, mit dem ich die Adresse ansprechen kann, gibt es im entsprechenden Bytecode diesen "Namen" auch nicht mehr, oder halt wie auch immer die Daten dort dargestellt sind. Ist das nicht so?
Was wäre dann zB ein Fall von einem Objekt, das im Bytecode referenziert ist, wofür ich aber im Quellcode keine Variable habe :bahnhof:
Verwalten die ganzen Dinge wie Lists und Arrays intern nicht auch einfach nur eine Menge an Variablen, in denen die einzelnen Referenzen liegen?

edit: Wäre ein Bsp dafür anonyme Klassen, oder?


----------



## Gast2 (1. Nov 2009)

hdi hat gesagt.:


> Wäre ein Bsp dafür anonyme Klassen, oder?


nein ... ein Byte-Code ist wie Assembler ... nur das Byte-Code von einer virtuellen CPU ausgeführt wird ... Assembler eben von einer richtigen ... der Vorteil liegt in den einfacheren parsen der Befehle - da Du richtig auf Bit-Ebene parsen kannst ... wobei das unter Java noch direkt in nativ übersetzt wird von dem ausführen


----------



## Spacerat (1. Nov 2009)

@hdi: Letztendlich reden wir vom gleichen. Aber erinnerst du dich noch an meine "geile" Erklärung? Die RT weiss nichts von unserem Quelltext, weil dieser vorher kompiliert wurde. Ottomormal-Entwickler weiss auch nicht, wie sein Quelltext in Bytecode aussieht. Möglicherweise will er das auch gar nicht wissen. Fakt ist aber, dass Quellcode sowie Bytecode die selben Dinge beschreiben. Einmal verständlich für den Entwickler, das andere mal verständlich für die RT. Aber wie gesagt: Ich bin eigentlich kein Erbsenzähler und denke, das dir Umstand bewusst ist, das man Quelltext vor der Ausführung in einer RT (Mom... das müsste dann ja auch RTE also RuntimeEnvironment bzw. Laufzeitumgebung heissen ) in Byte- bzw. Binärcode übersetzt werden muss.


----------



## Landei (1. Nov 2009)

Spacerat hat gesagt.:


> Fakt ist aber, dass Quellcode sowie Bytecode die selben Dinge beschreiben. Einmal verständlich für den Entwickler, das andere mal verständlich für die RT.



Einspruch, euer Ehren! Es gibt da nämlich eine wichtige Assymetrie: Jeder korrekte Quellcode kann in korrekten Bytecode umgewandelt werden, aber nicht jeder korrekte Bytecode in einen Quellcode. Oder anders ausgedrückt: java.exe lässt mehr "durchgehen" als javac.exe. Das ist nicht nur akademische Spielerei, ohne diese Eigenschaft ließen sich Bytecode-Enhancer und Nicht-Java-JVM-Sprachen nur noch sehr eingeschränkt (sprich: nicht mehr sinnvoll) implementieren.


----------



## Spacerat (1. Nov 2009)

Nicht stattgegeben: Dem Quelltext kann es egal sein, durch welchen Kompiler er zu welchem Bytecode wird und dem Bytecode durch welchen Recompiler zu welchem Quelltext. Theoretisch jedenfalls. Es wäre ja auch was, wenn mir ein Kompiler nicht genau die Klasse erstellt, die das tut was in meinem Quelltext steht, oder ein Recompiler mir nicht den Bytecode so wiedergeben würde, wie er aufgebaut ist. Die "akademische Spielerei" ist dann gegeben, wenn sich jemand einen Kompiler oder Recompiler entwickelt, der nichts weiter tut als Quelltext in einer ihm verständlichen Form in Bytecode einer anderen Umgebung oder umgekehrt übersetzt, ohne irgendwelche hilfreiche Erweiterungen zu implementieren. Z.B. Java-Bytecode in PHP-Quelltext (zwar utopisch, aber mir fällt dazu kein konkretes Beispiel ein) oder etwas völlig Neuem (z.B. Scala). Erst wenn sich dann aus Neuem irgendwann mal ein Sprachstandard entwickelt, wars das mit der "Spielerei". Das Neue ist plötzlich ernst zu nehmen. So geschehen bei Scala? BTW.: Scala für DotNet Schon gehört? Nu' wird's interessant.


----------



## Landei (2. Nov 2009)

Spacerat hat gesagt.:


> Nicht stattgegeben: Dem Quelltext kann es egal sein, durch welchen Kompiler er zu welchem Bytecode wird und dem Bytecode durch welchen Recompiler zu welchem Quelltext. Theoretisch jedenfalls. Es wäre ja auch was, wenn mir ein Kompiler nicht genau die Klasse erstellt, die das tut was in meinem Quelltext steht, oder ein Recompiler mir nicht den Bytecode so wiedergeben würde, wie er aufgebaut ist. Die "akademische Spielerei" ist dann gegeben, wenn sich jemand einen Kompiler oder Recompiler entwickelt, der nichts weiter tut als Quelltext in einer ihm verständlichen Form in Bytecode einer anderen Umgebung oder umgekehrt übersetzt, ohne irgendwelche hilfreiche Erweiterungen zu implementieren. Z.B. Java-Bytecode in PHP-Quelltext (zwar utopisch, aber mir fällt dazu kein konkretes Beispiel ein) oder etwas völlig Neuem (z.B. Scala). Erst wenn sich dann aus Neuem irgendwann mal ein Sprachstandard entwickelt, wars das mit der "Spielerei". Das Neue ist plötzlich ernst zu nehmen. So geschehen bei Scala? BTW.: Scala für DotNet Schon gehört? Nu' wird's interessant.



Ich glaube, wir reden aneinander vorbei. Bytecode *ist selbst* eine Sprache, und Bytecode erlaubt mehr als Java erlaubt. Punkt. Andere Sprachen und Bytecode-Tools können das ausnutzen.

Scala hat meines Wissens schon vom Urschleim an .Net Unterstützung, sie war halt nur nicht immer auf dem aktuellen Stand. Die Bemühungen scheinen in letzter Zeit intensiviert zu werden (gerüchteweise munkelt man von einem hochmotivierenden Scheck von M$ ans EPFL) Coderspiel / October 2009 (ganz rechts)


----------



## Spacerat (2. Nov 2009)

Landei hat gesagt.:


> Ich glaube, wir reden aneinander vorbei.


Das glaub' ich auch.





Landei hat gesagt.:


> Bytecode *ist selbst* eine Sprache...


Ahso... und wie sieht die als Quell- bzw. Klartext aus? Kann überhaupt irgendwer lesen, schreiben oder gar *sprechen* (das Vorlesen irgendwelcher Bytewerte mal ausgenommen), was sich hinter Bytecode verbirgt, ausser ein Interpreter bzw. De- oder JIT-Compiler? Die Tatsache, das sich hinter ein und demselben Bytecode verschiedene Sprachen verbergen können macht es längst nicht selbst zu einer. Um mogel's Worte mal in meine zu fassen: Bytecode ist eine Art Maschinencode, welcher, statt von einer CPU, von einem Interpreter oder JIT-Compiler ausgeführt wird. Aber nochmal: Das ist Erbsenzählerei. Deswegen hatte ich mogel's Satz ja auch eigentlich so stehen lassen.


----------



## Landei (2. Nov 2009)

Selbstverständlich kann das jemand als Assemblerversion mit entsprechenden Op-Codes "sprechen". Wie soll man sonst solche Sachen wie javassist oder FindBugs schreiben? Natürlich würde man damit keine "normalen" Applikationen basteln, aber Hexenwerk ist das bestimmt nicht (siehe z.B. Java bytecode: oder Jamaica, the JVM Macro Assembler)


----------



## Spacerat (2. Nov 2009)

Landei hat gesagt.:


> Selbstverständlich kann das jemand als Assemblerversion mit entsprechenden Op-Codes "sprechen".


Da wiederspreche ich auch gar nicht. Was genau heisst nun *Assemblerversion[/c]? Assembler ist 'ne Sprache, Maschinencode nicht. Im Bytecode steht nicht [c]JMP $2345[/c] sondern [c]4C 45 23[/c] (am Beispiel einer 6510 CPU).*


----------



## Landei (2. Nov 2009)

Ich meine sowas:

```
aload_0
invokespecial #3 <Method java.lang.Object()>
aload_0
aload_1
putfield #5 <Field java.lang.String name>
aload_0
iload_2
```


----------



## Spacerat (2. Nov 2009)

Landei hat gesagt.:


> Ich meine sowas:
> 
> ```
> aload_0
> ...


Das hab' ich mir gedacht (bzw. das war mir klar). Und? Sieht der Bytecode so aus? Oder ist das nun eine mehr oder weniger verständlichere Interpretation von jenem?


----------



## Landei (4. Nov 2009)

Spacerat hat gesagt.:


> Das hab' ich mir gedacht (bzw. das war mir klar). Und? Sieht der Bytecode so aus? Oder ist das nun eine mehr oder weniger verständlichere Interpretation von jenem?



Der Unterschied ist nun wirklich marginal. Wenn man _das_ aus dem FF kann, kann man sich theoretisch auch noch die Bytewerte reinkloppen - aber warum sollte man das tun?


----------

