What is an efficient way to test in java that in a given string all containing digits are in ascending order?
Example strings might be
String ascending = "Welc2ome T3o Co3mp67uter W99orld";
String notAscending = "Welc8ome T3o Co3mp67uter W99orld";
Avoid using String.split
or Integer.parseInt
because it not efficient.
If international digits and unicode character should be supported the following might be a solution.
public static boolean isNumericValuesAscending(String s) {
int max = -1;
for (int i = 0; i< s.length(); i++) {
char current = s.charAt(i);
boolean isDigit = Character.isDigit(current);
if (isDigit) {
int currentNumericValue = Character.getNumericValue(current);
if (max <= currentNumericValue) {
max = currentNumericValue;
} else {
return false;
}
}
}
return true;
}
If the if condition max <= currentNumericValue
is changed to max < currentNumericValue
, duplicate numeric values like T3o Co3
and W99orld
are not allowed.
It can be implemented in a more concise way using Java Streams + AtomicInteger
to track previous digit:
public static boolean ascendingDigits(String s) {
AtomicInteger prev = new AtomicInteger('0');
return s.chars()
.mapToObj(c -> (char)c) // Stream of Character
.filter(Character::isDigit) // filter digits including Unicode ranges
.allMatch(c -> prev.getAndSet(c) <= c); // compare previous digit to current and update the previous one
}
Test:
String asc = "Welc2ome T3o Co3mp67uter W89orld\uFF10 \uFF15 \uFF17"; // using fullwidth digits
System.out.println(asc);
System.out.println(ascendingDigits(asc));
String notAscending = "Welc8ome T3o Co3mp67uter W99orld";
System.out.println(ascendingDigits(notAscending));
Output:
Welc2ome T3o Co3mp67uter W89orld0 5 7
true
false