Java / Processing: Anzahl der Ziffern der kürzesten Zahl aus einem Array zurückliefern?
Hallo,
ich würde gern die Anzahl der Ziffern der kürzesten Zahl aus einem Array zurückliefern. Ich bin bisher soweit gekommen:
int findLow(int[] zahlen) {
int min = 0;
for (int i = 0; i < zahlen.length; i++) {
if (zahlen < zahlen[min])
min = i;
}
return min;
}
Aber das stimmt noch nicht so ganz.
3 Antworten
Es gibt wie immer verschiedene Wege, das Ziel zu erreichen. Ich hab dir mal eine Auswahl aus acht Funktionen gebaut. Kommentare im Code.
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.ToIntFunction;
public class MinLen {
public static void main(String[] args) {
// Testroutine. Die Umwandlungen passieren in den Methoden unten.
int[][] testCases = new int[][]{
// Nur positiv
{126425, 12345, 123, 12, 112},
// positiv und negativ
{126425, 12345, 123, 12, 112, -126425, -12345, -123, -12, -112},
// positiv und negativ (kürzere Negativzahlen)
{123, -12, 456, -45}
};
// Liste aller Funktionen erstellen
Map<String, ToIntFunction<int[]>> functions = new LinkedHashMap<>();
functions.put("findLow1", MinLen::findLow1);
functions.put("findLow1s", MinLen::findLow1s);
functions.put("findLow2", MinLen::findLow2);
functions.put("findLow2s", MinLen::findLow2s);
functions.put("findLow3", MinLen::findLow3);
functions.put("findLow3s", MinLen::findLow3s);
functions.put("findLow4", MinLen::findLow4);
functions.put("findLow4s", MinLen::findLow4s);
// Jede Testreihe mit jeder Funktion laufen lassen.
for (int[] testCase: testCases) {
System.out.println("Testzahlen: " + Arrays.toString(testCase));
functions.forEach((name, function) -> System.out.println(name + ": " + function.applyAsInt(testCase)));
System.out.println();
}
}
private static int findLow1(int[] input) {
// kleinste Zahl finden und davon die Länge ermitteln
// Achtung: Bei negativen Zahlen wird die längste gefunden,
// also z.B bei [1,14,-750] ist das Ergebnis 4 für "-750"
// Variable zur Suche nach der kleinsten Zahl erzeugen
// Startwert: Integer.MAX_VALUE (also die größte Zahl, die als int darstellbar ist)
int kleinsteZahl = Integer.MAX_VALUE;
// Alle Zahlen in der Liste durchgehen
for (int zahl: input) {
// falls die aktuelle Zahl kleiner als die bisherige kleinste Zahl ist,
// kleinsteZahl auf zahl setzen.
if (zahl < kleinsteZahl) {
kleinsteZahl = zahl;
}
// Alternativ: kleinsteZahl = Math.min(kleinsteZahl, zahl);
// Also "setze kleinsteZahl auf das kleinere aus kleinsteZahl und zahl
}
// Länge der kleinsten Zahl zurückgeben
return Integer.toString(kleinsteZahl).length();
}
private static int findLow1s(int[] input) {
// findLow1 als Stream
return Integer.toString(Arrays.stream(input).min().getAsInt()).length();
}
private static int findLow2(int[] input) {
// kleinsten Absolutwert finden und davon die Länge ermitteln
// Fast das Gleiche, wie findLow1, nur dass bei negativen Werten das Minus abgeschnitten wird
// Variable zur Suche nach der kleinsten Zahl erzeugen
// Startwert: Integer.MAX_VALUE (also die größte Zahl, die als int darstellbar ist)
int kleinsteZahl = Integer.MAX_VALUE;
// Alle Zahlen in der Liste durchgehen
for (int zahl: input) {
// falls die aktuelle Zahl kleiner als die bisherige kleinste Zahl ist,
// kleinsteZahl auf zahl setzen.
if (Math.abs(zahl) < kleinsteZahl) {
kleinsteZahl = Math.abs(zahl);
}
// Alternativ: kleinsteZahl = Math.min(kleinsteZahl, Math.abs(zahl));
// Also "setze kleinsteZahl auf das kleinere aus kleinsteZahl und Math.abs(zahl)
}
// Länge der kleinsten Zahl zurückgeben
return Integer.toString(kleinsteZahl).length();
}
private static int findLow2s(int[] input) {
// findLow2 als Stream
// (hier werden erst alle Werte in ihren Absolutwert umgewandelt und dann erst der Kleinste gesucht.)
return Integer.toString(Arrays.stream(input).map(Math::abs).min().getAsInt()).length();
}
private static int findLow3(int[] input) {
// tatsächlich die Länge der Zahlen vergleichen
// Achtung: Bei negativen Zahlen wird das minus zur Länge mitgezählt,
// also z.B. -123 hat die Länge 4.
// Variable zur Suche nach der kürzesten Zahl erzeugen
// Startwert: Integer.MAX_VALUE (also die größte Zahl, die als int darstellbar ist)
int kuerzesteLaenge = Integer.MAX_VALUE;
// Alle Zahlen in der Liste durchgehen
for (int zahl: input) {
// falls die aktuelle Zahl kürzer als die bisherige kürzeste Zahl ist,
// kuerzesteLaenge auf Länge von zahl setzen.
if (Integer.toString(zahl).length() < kuerzesteLaenge) {
kuerzesteLaenge = Integer.toString(zahl).length();
}
// Alternativ: kuerzesteLaenge = Math.min(kuerzesteLaenge, Integer.toString(zahl).length());
// Also "setze kuerzesteLaenge auf das kleinere aus kuerzesteLaenge und Länge von zahl
}
// Länge der kürzesten Zahl zurückgeben
return kuerzesteLaenge;
}
private static int findLow3s(int[] input) {
// findLow3 als Stream
// (hier werden erst die Längen aller Werte ermittelt und dann erst der Kleinste gesucht.)
return Arrays.stream(input).map(n -> Integer.toString(n).length()).min().getAsInt();
}
private static int findLow4(int[] input) {
// Kombination aus findLow2 und findLow3,
// Also die tatsächliche Länge vergleichen, aber vorher das Minus abschneiden
// Variable zur Suche nach der kürzesten Zahl erzeugen
// Startwert: Integer.MAX_VALUE (also die größte Zahl, die als int darstellbar ist)
int kuerzesteLaenge = Integer.MAX_VALUE;
// Alle Zahlen in der Liste durchgehen
for (int zahl: input) {
// falls die aktuelle Zahl kürzer als die bisherige kürzeste Zahl ist,
// kuerzesteLaenge auf Länge von zahl setzen.
if (Integer.toString(Math.abs(zahl)).length() < kuerzesteLaenge) {
kuerzesteLaenge = Integer.toString(Math.abs(zahl)).length();
}
// Alternativ: kuerzesteLaenge = Math.min(kuerzesteLaenge, Integer.toString(Math.abs(zahl)).length());
// Also "setze kuerzesteLaenge auf das kleinere aus kuerzesteLaenge und Länge von zahl
}
// Länge der kürzesten Zahl zurückgeben
return kuerzesteLaenge;
}
private static int findLow4s(int[] input) {
// findLow4 als Stream
// (Vor dem Vergleich werden wieder die Umwandlungen gemacht)
return Arrays.stream(input).map(Math::abs).map(n -> Integer.toString(n).length()).min().getAsInt();
}
}
Danke dir. Werde mal alles ausprobieren. Bisher hat nichts funktioniert.
Suche erst die kleinste Zahl im Array.
Pseudocode:
min = numbers[0]
for i = 1, i < len(numbers), ++i
if min > numbers[i]
min = numbers[i]
Und teile danach die ermittelte Zahl so lange durch 10, bis sie selbst kleiner als 0 ist. Die Anzahl an Teilungen musst du mitzählen.
Beispiel:
125 / 10 = 12
12 / 10 = 1
1 / 10 = 0
=> 3 Zahlen
Da die Division mit ganzen Zahlen erfolgt, wird auch die Nachkommastelle abgetrennt. Sie ist für diese Berechnung eh nicht wichtig.
PS.: Mein Pseudocode geht davon aus, dass das Array mindestens einen Eintrag hat. Sollte dem nicht so sein, müsstest du dir eine Fehlerbehandlung einfallen lassen.
Des Weiteren wird für Teil 2 noch nicht beachtet, dass im Array auch negative Zahlen vorhanden sein könnten. Daher sollte vom Minimum erst der Betrag berechnet werden. Processing bietet dafür die abs-Funktion.
Für den letzten Schritt kann man auch einfach den 10er-Logarithmus +1 nehmen.
int findLow(int[] zahlen) {
int min = 9999999; //eine hohe Zahl
for (int i=0; i < zahlen.length; i++) {
if ( zahlen[i] < min) {
min = zahlen[i];
}
}
return min;
}
Das gibt aber nicht die Anzahl der Ziffern zurück.
Das Ergebnis sollte so aussehen:
findLow([1,2,3,4]) --> liefert 1
findLow([126425,12345,123,12,112]) --> liefert 2
True, das hab ich vergessen.
Tausch beide
zahlen[i]
mit
(int)(Math.log10(zahlen[i])+1)
aus.
Kann man das nicht irgendwie in eine String umwandeln? Ich wüsste dann nicht wie ich daraus die kleinste Zahl herausbekomme
String.valueOf https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#valueOf(int)
Tests nochmal, hab meine Antwort da noch editiert, das sollte eigtl schon gehen, so wie sie jetz is.
Kannst du natürlich auch machen, is aber Performancetechnisch nich zu empfehlen.
Hat endlich funktioniert. Vielen Dank nochmal :)