Prüfen ob Ziffern einer Zahl pandigital sind?

Status
Nicht offen für weitere Antworten.
G

Großvater

Gast
Hallo ihr,

ich würde gerne große Zahlen(BigIntegers) prüfen ob die ersten 9 Ziffern (ohne die 0) pandigital sind. Pandigitale Zahlen enthalten alle Ziffern von 1-9 (eigentlich 0-9), aber nicht unbedingt in der richtigen Reihenfolge. Bsp: 123456789, 987654321, 561234789

Angenommen ich habe jetzt eine große Zahl (BigInteger) wie z.B. die hier:

43466557686937456435642996440906533187938298969649928516003704476137795166849228875

Wie könnte ich möglichst effizient (schnell) prüfen, ob die ersten 9 Ziffern pandigital sind?

Hier meine Lösung (die aber viieeeel zu langsam ist):
Code:
public static boolean ispandigital(BigInteger x){
	String s = x.toString();
	if(s.length()<18){
		return false;
	}
	else{
		ArrayList<String> list = new ArrayList();
		for(int i=0;i<9;i++){
			String temp = s.substring(i,i+1);
			list.add(temp);
		}
		if(list.contains("1") && list.contains("2") && list.contains("3") && list.contains("4") && list.contains("5") && list.contains("6") && list.contains("7") && list.contains("8") && list.contains("9")){
			System.out.println("zahl gefunden: "+s);
			return true;
		}
		else{
			return false;
		}
	}
}

Das muss doch besser gehen!
 

The_S

Top Contributor
Evtl. ist die Überprüfung der Quersumme schneller. Frag mich jetzt aber nicht, wie du am effektivsten von einem BigInteger auf die Quersumme der ersten neun Ziffern kommst
 
S

SlaterB

Gast
wenn du bei String bleibst, dann arbeite wenigstens mit charAt(i)-48, dann hast du 0-9
und dann in ein boolean[] nachschauen, wenn eine Zahl schon vorhanden ist false,
ansonsten (9x nicht false) muss es geklappt haben,

toString() sieht im Code aber recht aufwendig aus,
vielleicht hilft es, mit shiftRight(n) die Zahl auf die Länge eines int oder long zu kürzen,
oder die toByteArray()-Operation ausprobieren,

wäre beides aber mit aufwendigeren Berechnungen verbunden,
und ob das schneller oder langsamer ist, wäre auch noch zu testen ;)
 
G

Guest

Gast
Großvater hat gesagt.:
Wie könnte ich möglichst effizient (schnell) prüfen, ob die ersten 9 Ziffern pandigital sind?
Du kannst in einer int-Variable für jede Ziffer ein Bit reservieren und dann bei jeder eingelesenen Ziffer das entsprechende Bit setzen. Am Ende prüfst Du dann einfach, ob die 9 richtigen Bits gesetzt sind:

Code:
public static boolean ispandigital(BigInteger x)
{
	String string = x.abs().toString();
	int ziffern = 0;
	for (int i = 0, sup = Math.min(string.length(), 9); i < sup; ++i)
		ziffern |= 1 << (string.charAt(i) - '0');
	
	return ziffern == 1022;
}

Fred
 

moormaster

Top Contributor
Kann man nicht einfach den String Zeichen für zeichen durchwandern?:

Code:
//Skizze
checksum = 0

für jedes Zeichen c aus dem String:
{
  n = Integer.parseInt(c);  // Ziffer bestimmen
  checksum |= (int)Math.pow(2, n) // n-tes Bit von checksum setzen
                                                  // das geht sicher noch effizienter, als wirklich mit Math.pow zu arbeiten
                                                  // z.B. könnte man sich statt dessen ein Array mit den entsprechenden
                                                  // 2er Potenzen zurechtlegen und dann nur die Elemente daraus abfragen
}

// Wenn nun alle Ziffern von 0-9 enthalten waren, dann gilt
// checksum & (2^10-1) == (2^10-1)

// Analog gilt:
// checksum & (2^10-1 - 1) == (2^10-1 - 1)
// wenn Ziffern 1-9 enthalten waren

//d.h. pandigital für 0-9
return checksum & (2^10-1) == (2^10-1);

//ODER pandigital für 1-9
return checksum & (2^10-1 - 1) == (2^10-1 - 1)
 
S

SlaterB

Gast
also charAt ist auf jeden Fall besser als Integer.parseInt, bzw. aus dem char musst du nicht mehr parsen, einfach -48,
für das Math.pow hat ja jemand zeitgleich das Shift vorgeschlagen

die (Quer-) Summe reicht aber wohl aus und ist dann noch besser als das Shiften?
letzlich egal, solange nur substring wegfällt (oder gar Integer.parseInt)
 
G

Guest

Gast
SlaterB hat gesagt.:
die (Quer-) Summe reicht aber wohl aus und ist dann noch besser als das Shiften?
Ich glaube nicht, dass die Quersumme ausreicht. Sonst würde 111159999 auch als pandigital anerkannt werden, oder?

Fred
 

moormaster

Top Contributor
SlaterB hat gesagt.:
also charAt ist auf jeden Fall besser als Integer.parseInt, bzw. aus dem char musst du nicht mehr parsen, einfach -48,
für das Math.pow hat ja jemand zeitgleich das Shift vorgeschlagen

die (Quer-) Summe reicht aber wohl aus und ist dann noch besser als das Shiften?
letzlich egal, solange nur substring wegfällt (oder gar Integer.parseInt)

Mit der Quersumme wäre ich aber vorsichtig... Wenn ich nur schaue, ob die ersten 9 Ziffern summiert == 9*10/2 (-> 45) sind, dann wäre auch
997654320... pandigital, weil 9+9+7+6+5+4+3+2+0 == 45

Man muss also sicherstellen können, dass eine Ziffer nicht doppelt gezählt werden, was bei einer ODER-Verknüpfung der Fall wäre

*Mist schonwieder zu langsam... das kommt davon, wenn man abgelenkt wird beim Schreiben... :D*
 
G

Guest

Gast
SlaterB hat gesagt.:
toString() sieht im Code aber recht aufwendig aus,
Das könnte tatsächlich der eigentliche Flaschenhals sein.

Was machst Du denn so mit den Zahlen, bevor Du sie auf Pandigitalität überprüfst? Wird da viel gerechnet, oder werden die vielleicht einfach nur aus einer Textdatei gelesen? Dann würde es Sinn machen, sie gleich ausschließlich als Strings zu behandeln.

Schreib doch mal den Code auf, der ispandigital benutzt.

Fred
 
G

Guest

Gast
Die toString()-Methode IST der Flaschenhals:

Code:
public static boolean ispandigital(BigInteger x)
{
	Benchmark bm = new Benchmark();
	bm.start();
	String string = x.abs().toString();
	bm.stop("toString");

	bm.start();
	int ziffern = 0;
	for (int i = 0, sup = Math.min(string.length(), 9); i < sup; ++i)
		ziffern |= 1 << (string.charAt(i) - '0');
	bm.stop("Ziffern");

	bm.start();
	ArrayList<String> list = new ArrayList();
	for (int i = 0; i < 9; i++)
	{
		String temp = string.substring(i, i + 1);
		list.add(temp);
	}
	boolean ergebnis = list.contains("1") && list.contains("2") && list.contains("3")
			&& list.contains("4") && list.contains("5") && list.contains("6")
			&& list.contains("7") && list.contains("8") && list.contains("9");
	bm.stop("Liste");

	return ziffern == 1022;
}

Die letzten Messung lautet:
*** toString: 4740 ns
*** Ziffern: 450 ns
*** Liste: 2585 ns

toString() braucht ganz grob 10x so lange wie der optimierte Algorithmus. Obwohl die Ziffern-Version also 6x so schnell ist wie Listen-Version, ist die komplette Methode aufgrund der Laufzeit von toString() insgesamt nur 40% schneller geworden.

Fred
 

moormaster

Top Contributor
Du musst es ja auch nicht als String behandeln... man kann doch Ganzzahlen auch per Modulo in ihre Ziffern zerlegen:

1432%10 = 2 -> 1432/10=143
143%10 = 3 -> 143/10 = 14
14%10 = 4 -> 14/10 = 1
1%10 = 1 -> 1 /10 = 0 -> halt

=> 1,4,3,2

Bezüglich BigInteger gibt es entsprechende Methoden, welche statt der "primitven" Operatoren verwendet werden können. Möglicherweise ist es bei besonders langen Ganzzahlen günstiger, den BigInteger stückweise in primitive int's zu verwandeln und diese dann nach obigem Schema zu zerlegen, wobei die Ergebnisse zum Schluss zusammengefügt werden.
 
S

SlaterB

Gast
tja, es ist aber gerade die Frage, wie man aus einem BigInteger die Ziffern rauskriegt,
eine 'Ganzzahl' hat man da nicht so leicht, toString() schon eher

edit:
> Bezüglich BigInteger gibt es entsprechende Methoden

oh, welche? außer du meinst, die ganze Zahl modulo zu rechnen
 

moormaster

Top Contributor
SlaterB hat gesagt.:
tja, es ist aber gerade die Frage, wie man aus einem BigInteger die Ziffern rauskriegt,
eine 'Ganzzahl' hat man da nicht so leicht, toString() schon eher
BigInteger ist doch die Repräsentation einer Ganzzahl... nur eben leider nicht als primitiver Datentyp

edit:
> Bezüglich BigInteger gibt es entsprechende Methoden

oh, welche? außer du meinst, die ganze Zahl modulo zu rechnen

Genau das meinte ich... Die BigInteger-Klasse stellt Methoden zum Dividieren und zur Modulorechnung von Biginteger'n bereit, weil ja % und / nicht direkt darauf angewendet werden können. Da das wahrscheinlich auch eine längere Rechenzeit in Anspruch nimmt, als wenn man es mit primitiven Datentypen zu tun hätte, hab ich ja auch vorgeschlagen, den BigInteger nicht ziffernweise zu zerlegen, sondern erstmal Gruppenweise...

BigInt mod 10^gruppenlaenge = letzte Gruppe -> BigInt div 10^gruppenlaenge (letzte Gruppe entfernen)
usw.

die Gruppen könnte man dann per intValue zu int wandeln und dann diese Gruppen mit % und / in Ziffern zerlegen.
 

NTB

Bekanntes Mitglied
Wenn man gegen richtig viele Zahlen prüft, kann es durchaus Sinn machen, die Quersumme erstmal zu berechnen. Wenn die Quersumme 45 ist, dann eben weiter untersuchen.
Das wäre zwar an sich bischen länger, aber man schließt Zahlen viel schneller aus.
 

moormaster

Top Contributor
NTB hat gesagt.:
Wenn man gegen richtig viele Zahlen prüft, kann es durchaus Sinn machen, die Quersumme erstmal zu berechnen. Wenn die Quersumme 45 ist, dann eben weiter untersuchen.
Das wäre zwar an sich bischen länger, aber man schließt Zahlen viel schneller aus.

Ich bezweifle, dass eine Addition so viel schneller ist, als eine simple Bitoperation... auch für die Quersumme muss man schliesslich erstmal an die einzelnen Ziffern kommen (was, wie ich denke, der aufwendigste Teil der Sache ist).
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
8u3631984 Prüfen ob min. ein Element eines Sets in einem anderen Set enh Allgemeine Java-Themen 4
OnDemand Prüfen ob Bild defekt ist Allgemeine Java-Themen 4
N Prüfen, ob ein String 2x das selbe Zeichen hat Allgemeine Java-Themen 10
W Classpath Reflexion - Prüfen ob man auf ein Feld ändern kann Allgemeine Java-Themen 2
OnDemand Bild prüfen ob defekt Allgemeine Java-Themen 3
B Java Mail: Prüfen, ob Email hat ein Anhang oder nicht Allgemeine Java-Themen 2
Bluedaishi Prüfen ob Datei noch geöffnet ist Allgemeine Java-Themen 59
Stonie Prüfen von direkter Implementierung eines Interfaces Allgemeine Java-Themen 7
J Mit Lombok Integer Range prüfen Allgemeine Java-Themen 6
S Prüfen ob Textfile existiert Allgemeine Java-Themen 9
E Programm auf Installation prüfen Allgemeine Java-Themen 1
S Binärbaum prüfen Allgemeine Java-Themen 0
L String auf zahlenwert prüfen Allgemeine Java-Themen 13
W Datum prüfen + zweistellig Allgemeine Java-Themen 11
perlenfischer1984 Functionsparameter prüfen und eine Exception werfen !? Allgemeine Java-Themen 11
Z Java Exceptions - Auf leeres Feld prüfen Allgemeine Java-Themen 10
F Wie kann ich auf einem System prüfen, ob eine lib verfügbar ist? Allgemeine Java-Themen 2
P Prüfen ob es Variable mit Namen gibt der als String übergeben wird Allgemeine Java-Themen 7
M .jar nach Datei prüfen Allgemeine Java-Themen 2
B Existenz eines Files max 30 sec prüfen Allgemeine Java-Themen 5
B Prüfen, ob ein Element in der Liste nicht existiert Allgemeine Java-Themen 3
F Cardlayout prüfen ob schon vorhanden, keine doppelten Allgemeine Java-Themen 3
turmaline Regex gegen Regex prüfen Allgemeine Java-Themen 4
S Lambda Ausdrücke: @FunctionalInterface Instanzen auf null prüfen Allgemeine Java-Themen 9
D ArrayList index auf gültigkeit prüfen Allgemeine Java-Themen 12
C Best Practice [Arrays] Wie sinnvoll prüfen, ob Array primitive Datentypen enthält? Allgemeine Java-Themen 6
L Prüfen, ob Programm über 32bit oder 64bit Java ausgeführt wird Allgemeine Java-Themen 4
K Methoden Arrays auf true Werte prüfen Allgemeine Java-Themen 4
Y Prüfen ob ein Graph immer einen von mehren Enden erreicht Allgemeine Java-Themen 4
O Prüfen ob String eine Zahl mit maximal 2 Nachkommastellen ist Allgemeine Java-Themen 4
M datei aufruf prüfen Allgemeine Java-Themen 9
D Best Practice Prüfen ob jar nachträglich geändert wurde Allgemeine Java-Themen 2
B Dateien prüfen auf Gleichheit Allgemeine Java-Themen 5
H String auf Zahlen prüfen Allgemeine Java-Themen 4
T auf Valides Datum prüfen Allgemeine Java-Themen 12
N Java Version Prüfen lassen Allgemeine Java-Themen 11
S Variablen Prüfen ob Number vom Typ Integer, Float, Double, ... ist Allgemeine Java-Themen 2
E selber Klassen kompilieren/ prüfen Allgemeine Java-Themen 5
O Variablen Originalname einer übergebenen Variable prüfen Allgemeine Java-Themen 9
T Methoden Zahlenpalindrom laufzeitoptimiert prüfen Allgemeine Java-Themen 4
U ResourceBundles auf vollständigkeit prüfen Allgemeine Java-Themen 2
C jollyday: prüfen, ob Datum = Feiertag Allgemeine Java-Themen 8
C Prüfen ob sich ein Punkt innerhalb einer Kugel befindet (Java3D,nicht-lineare GLS) Allgemeine Java-Themen 5
M Objekt prüfen auf null ->Invocation Target Exception??? Allgemeine Java-Themen 2
E Prüfen ob Fenster mit Namen offen ist Allgemeine Java-Themen 2
M Binärbaum auf vollständigkeit prüfen Allgemeine Java-Themen 4
S Mail Adressen Syntax prüfen Allgemeine Java-Themen 22
O Text mit Wildcard gegen regulären Ausdruck prüfen Allgemeine Java-Themen 3
N List auf null prüfen Allgemeine Java-Themen 2
B generischen Typ prüfen Allgemeine Java-Themen 7
D prüfen, ob Enums bestimmte Elemente enthalten Allgemeine Java-Themen 3
N Prüfen ob Methode ausgeführt wird und diese ggf. abbrechen? Allgemeine Java-Themen 8
B Prüfen ob ein Programm gestartet wurde Allgemeine Java-Themen 23
N ArrayList nach Reihenfolge prüfen Allgemeine Java-Themen 2
C Prüfen auf Zahl und 6 stellig fehlerhaft? warum? Allgemeine Java-Themen 7
D Wie prüfen, ob ein String Teil eines Enum Types ist? Allgemeine Java-Themen 12
H Prüfen, ob doppete Werte in int-Array vorhanden sind Allgemeine Java-Themen 16
data89 Bilder mit Java prüfen - suche dringend Hilfe Allgemeine Java-Themen 8
S Prüfen auf Hex-Wert fester Länge! Allgemeine Java-Themen 5
M Prüfen, welche anderen Programme laufen Allgemeine Java-Themen 5
K Zip dateien prüfen Allgemeine Java-Themen 3
G ZIP Archiv auf Konsistenz prüfen Allgemeine Java-Themen 2
T Parameter einer Klasse auf Interface prüfen Allgemeine Java-Themen 6
L Passwort mit Regulärem Ausdruck prüfen Allgemeine Java-Themen 6
P Sound Buffer prüfen Allgemeine Java-Themen 12
B PrintService - Wie prüfen ob Drucker online ist? Allgemeine Java-Themen 2
A Textfeld prüfen, ob ein Punkt eingegeben wurde Allgemeine Java-Themen 8
flashfactor Prüfen ob bereits eine Instanz gestartet ist Allgemeine Java-Themen 2
C Prüfen, ob eine Methode eine andere überschreibt! WIE? Allgemeine Java-Themen 8
T Prüfen, ob Char ein Quantifier ist Allgemeine Java-Themen 6
N Prüfen ob Objekt in Liste enthalten ist Allgemeine Java-Themen 17
G Prüfen welche JRE-Version gebraucht wird Allgemeine Java-Themen 19
J Mit Patternmatching einen Satz prüfen Allgemeine Java-Themen 12
M Prüfen ob Variable vorhanden / initalisiert ist Allgemeine Java-Themen 4
J Wie prüfen ob eine Datei vom OS fertig geschrieben wurde? Allgemeine Java-Themen 6
TheJavaKid Zeile auf existenz von String prüfen. Allgemeine Java-Themen 19
A Weshalb man Parameter auf Gültigkeit prüfen sollte Allgemeine Java-Themen 6
N Prüfen ob ein String in einen Integer umgewandelt werden kan Allgemeine Java-Themen 4
O String auf zahlen prüfen (java 1.3) Allgemeine Java-Themen 4
G Datei Zugriffsrechte prüfen Allgemeine Java-Themen 2
Linad Bilder auf Gleichheit prüfen Allgemeine Java-Themen 6
G ResultSet auf Inhalt prüfen? Allgemeine Java-Themen 2
H Prüfen, ob es sich um ein Integer handelt Allgemeine Java-Themen 4
C String str prüfen Allgemeine Java-Themen 3
H Prüfen ob ein String grösser als 4 Zeichen ist Allgemeine Java-Themen 3
F Prüfen, ob Windows oder UNIX Allgemeine Java-Themen 2
J Rekursive Programmierung-Zählen von Ziffern Allgemeine Java-Themen 5
S Ziffern auf Existenz überprüfen Allgemeine Java-Themen 13
brunothg Alle Kombiationen von n Ziffern Allgemeine Java-Themen 2
K Webcam Ziffern ablesen Allgemeine Java-Themen 7
T Strings darf nur Ziffern, +/- haben Allgemeine Java-Themen 9
MQue Anzahl der Ziffern Allgemeine Java-Themen 13
V String formatiert ausgeben ( gleiche Anzahl von Ziffern ) Allgemeine Java-Themen 5
G ziffern zählen mit rekursiver methode Allgemeine Java-Themen 2
N String überprüfen ob nur Ziffern enthalten sind!! Allgemeine Java-Themen 8
P Verschiedene Aspekte einer idempotent API verstehen? Allgemeine Java-Themen 16
Zrebna Ausführung einer Testmethode in der IDE erfolgreich - failt aber via 'mvn test' Allgemeine Java-Themen 5
S Interpreter-Fehler Kann mir das mal einer erklären? Allgemeine Java-Themen 12
Zrebna Aus einer jar-Datei eine exe-Datei erzeugen lassen Allgemeine Java-Themen 37
O Text aus einer Textdatei rausholen, der zwischen zwei Schlüsselworten steht Allgemeine Java-Themen 4

Ähnliche Java Themen


Oben