![]() |
|
|
Themen-Optionen |
|
|
Nach oben #1 |
|
Gast
Beiträge: n/a
|
Hallo Leute,
weil es so viel Spass macht gleich noch ein Post. Nein im Ernst, nachdem ich schon mehrere Wochen vergeblich nach einer vernünftigen Lösung suche wie man eine x-stellige positive ganze Zahl per Random erzeugt, in der dann auch noch jede Ziffer von 0 bis 9 nur einmal vorkommt dachte ich ich poste diese Frage mal hier. Das wird bestimmt andern Programmieren auch weiterhelfen. Gruß Olli |
|
|
|
Nach oben #2 |
|
Erfahrener Benutzer
Registriert seit: 02.02.2005
Beiträge: 515
|
Hab ich das richtig verstanden
x-Stellig, also z. B. 64684 241243234123 23131 5 zahl von 0 - 9 nur einmal (was dann gleichzeitig wieder auf 10 Stellen begrenzen würde) 1234567890 = darf sein 22 = darf nicht sein oder doch anders? |
|
|
|
|
|
Nach oben #4 |
|
Benutzer
Registriert seit: 15.11.2005
Beiträge: 75
|
Normalerweise würde man (Pseudo-)Zufallszahlen ja mit der Klasse java.util.Random erzeugen. Hier geht es aber nicht wirklich um Zufallszahlen, sondern darum, eine zufällige Anzahl von Zeichen aus dem Vorrat '0'..'9' in eine zufällige Reihenfolge zu bringen.
Ein m.E. schöner Ansatz wäre eine Analogie zum Kartenmischen - nicht die Angebermethode mit den zwei Stapeln, die man dicht nebeneinanderlegt und dann daumenkinoartig ineinander verschränkt, auch nicht die Grobmotorikervariante, bei der man alle Karten auf den Tischen fallen lässt und dann mit der Hand durcheinandermischt (Loriot lässt grüßen), sondern ganz einfach: die eine Hand hält den Stapel, die andere nimmt eine zufällige Anzahl Karten von oben ab und schiebt sie unter den Rest. Also: Baue eine String aus den Ziffern '0' bis '9'. Das kann man entweder als String-Konstante machen (einfach, effizient, langweilig), oder in einer Schleife dynamisch erzeugen (eindeutig der höhere Geek-Faktor). Dann wird eine Zufallszahl n erzeugt, die die Anzahl der Vermischungen angibt. Dann läuft eine for-Schleife, in der n-mal der String analog zum Kartenmischen vermischt wird: teile den String an einer beliebigen Stelle und vertausche die Reihenfolge der beiden Teile. Zum Schluss wird noch eine Zufallzahl l zwischen 1 und 10 bestimmt, die die Länge der Zahl bestimmt. Nimmt nun die ersten l Zeichen des Strings und mach daraus mit Integer.parseInt eine Zahl. Voila! (Das ist bestimmt kein besonders effizienter Algorithmus, aber doch irgendwie charmant) |
|
|
|
|
|
Nach oben #5 |
|
Projektleiter
Registriert seit: 30.11.2005
Ort: Bottrop
Beiträge: 1.091
|
PHP-Code:
Theorie: Wir zerlegen die Zahl in ihre Bestandteile und errechnen den Wert jeder einzelnen Stelle in der Form n*10^x. Beispiel: Code:
x = 0; i = 2; n = rand() = 5 => x += 5 * 10^2 = 5 * 100 = 500 i = 1; n = rand() = 1 => x += 1 * 10^1 = 10 => x = 510 i = 0; n = rand() = 3 => x += 3 * 10^0 = 3 => x = 513 Edit: Ok... quote- und code-BBCode zu verwechseln ist nun wirklich selten dämlich. Nun kann man's hoffentlich entziffern.
__________________
Patrick Gotthardts Weblog. |
|
|
|
|
|
Nach oben #6 |
|
Gast
Beiträge: n/a
|
@Murray
Ich find ja die Idee an sich super und einfallsreich, aber ist das nicht ein wenig wie das Rad neu erfinden. Wie würde es denn aussehen, wenn wir die Zahl einfach mit der Random Klasse erzeugen und dann auf unsere Kriterien hin überprüfen. Werden diese nicht erfüllt, fällt sie durch. Das wäre so meine Idee, allerdings hab ich dafür noch keinen Source. Gruß Olli |
|
|
|
Nach oben #7 |
|
Projektleiter
Registriert seit: 30.11.2005
Ort: Bottrop
Beiträge: 1.091
|
Also meine Idee gefällt mir eigentlich.
Beim überprüfen der Zahl müsstest du sie wohl zwangsläufig in einen String umwandeln und unglaublich häßliche Spielchen veranstalten. Außerdem ist das mit Sicherheit eine Variante, die (im schlimmsten Fall) zu einer Endlosschleife führen kann - wer garantiert dir denn, dass du jemals per Zufall eine Zahl bekommst, die die Kriterien erfüllt?
__________________
Patrick Gotthardts Weblog. |
|
|
|
|
|
Nach oben #10 |
|
Projektleiter
Registriert seit: 30.11.2005
Ort: Bottrop
Beiträge: 1.091
|
Ich hatte es für Java 5 geschrieben (d.h. mit Generics).
Die Version für < 5 sieht so aus: PHP-Code:
__________________
Patrick Gotthardts Weblog. |
|
|
|
|
|
Nach oben #12 | |
|
Benutzer
Registriert seit: 15.11.2005
Beiträge: 75
|
Zitat:
Gerade bei großen Zahlen ist die Wahrscheinlichkeit doch recht hoch, dass die Zahl durchfallen wird (wie hoch, kann sicherlich ein Mathematiker bzw. Statistiker ausrechnen). Zu meinem Algorithmus (der natürlich nicht so effizient ist wie der von Pago Implementieren lässt sich das so: Code:
java.util.Random r = new java.util.Random();
StringBuilder sb = new StringBuilder();
for ( char c='0'; c <= '9'; c++) sb.append( c);
for ( int j=0; j<10; j++) {
int shuffle = r.nextInt( 9) + 2; //-- 2-10 Vertauschungen
String s = sb.toString();
for ( int i=0; i<shuffle; i++) {
int pos1 = r.nextInt(4)+1; //--- 1..4
int pos2 = r.nextInt(4)+5; //--- 5..9
String s1 = s.substring( 0, pos1);
String s2 = s.substring( pos1, pos2+1);
String s3 = s.substring( pos2+1, s.length());
s = s1 + s3 + s2;
}
int len = r.nextInt( 10) +1; //--- 1..10
long l = Long.parseLong( s.substring( 0, len));
System.out.println( "shuffle: " + shuffle + ",len: " + len + " -> " + l);
}
|
|
|
|
|
|
|
Nach oben #13 | |
|
Benutzer
Registriert seit: 15.11.2005
Beiträge: 75
|
Zitat:
|
|
|
|
|
|
|
Nach oben #14 | |
|
Projektleiter
Registriert seit: 30.11.2005
Ort: Bottrop
Beiträge: 1.091
|
Zitat:
0 * 10^x = 0 Hmm... Lösungsansatz ist nicht so besonders toll... wenn "number" = 0 ist, dann müssen wir statt 0 eine 10 verwenden. Bei der nächsten Zahl müssen wir dann 1*10^(x+1) abziehen. PHP-Code:
__________________
Patrick Gotthardts Weblog. |
|
|
|
|
|
|
Nach oben #15 |
|
Gast
Beiträge: n/a
|
Du hast eigentlich nichts vergessen. Deine letzten Änderungen haben sich so ausgewirkt, das das Programm nun 5 Stellige Zahlen generiert. Wir müssen es also nur abfangen, dass es eine führende Null gibt oder diese mit ausgegeben wird.
|
|
|
|
Nach oben #17 |
|
Gast
Beiträge: n/a
|
ich würde ich die Ziffern von 0-9 shuffeln und dann einfach die ersten x rausnehmen...
PHP-Code:
|
|