JavaNoob JavaNoob - 7 months ago 11
Java Question

My program doesn't print out Strings converted to ints

I have a simple program that asks you to enter numbers by keyboard (each number being separated by a space or by a comma) and then sorts them from lower to higher and prints them.

The problem is that the numbers aren't printed out.

Here is the source code:

import java.util.Scanner;

public class StartHere {
public static void main(String[] args) {

Scanner scanner = new Scanner(System.in);
System.out.print("Type random numbers: ");
String input = new String(scanner.nextLine());
scanner.close();
String[] numString = new String[input.length()];

int a = 0;
int i = 0;
for (; i < input.length() - 1;) {
if (Character.isDigit(input.charAt(a))) { // If the character at input[a] is a digit
numString[i] += Character.toString(input.charAt(a)); // it is added to numString[i]
if(!(a+1 > input.length())){
a++;
}
}
if (numString[i] != null && !Character.isDigit(input.charAt(a))) { // If numString[i] is already in use and the char at input[a] is not a digit
if(!(i+1 > input.length())){
i++;
}
if(!(a+1 > input.length())){
a++;
}
}
if (numString[i] == null && !Character.isDigit(input.charAt(a))){ // If numString[i] is not in used and the character at char[a] is not a digit.
if(!(a+1 > input.length())){
a++;
}
}
}
a = 0;
i = 0;
int[] numbers = new int[numString.length];
for(; i < numString.length - 1; i++){
numbers[i] = Integer.parseInt(numString[i]);
}
quicksort(numbers, 0, numbers.length - 1);
for(i = 0; i < numbers.length - 1; i++){
if(i != numbers.length){
System.out.print(numbers[i] + ", ");
}else{
System.out.println(numbers[i] + ".");
}
}
}
public static void quicksort(int numbers[], int left, int right) {

int pivot = numbers[left]; // takes the first element as pivot
int l = left; // l searches from left to right
int r = right; // r searches from right to left
int aux;

while(l<r){ // While searches doesn't cross
while((numbers[l] <= pivot) && (l < r)) l++; // searches for an element higher than the pivot
while(numbers[r] > pivot) r--; // Searches for an element smaller than the pivot
if (l<r) { // if searches haven't been crossed
aux = numbers[l]; // they are exchanged
numbers[l] = numbers[r];
numbers[r] = aux;
}
}
numbers[left] = numbers[r]; // The pivot is placed in a way that we have the
numbers[r] = pivot; // smaller digits at the left and the higher digits at the right
if(left < r-1)
quicksort(numbers, left, r-1); // left subarray is sorted
if(r+1 < right)
quicksort(numbers, r+1, left); // right subarray is sorted
}
}


EDITED: Added an
a++;
expression in the 26th line that prevents the program from entering into an infinite loop and a new
if
block that prevents the program from "freezing", but now I get this error:

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 16
at java.lang.String.charAt(Unknown Source)
at StartHere.main(StartHere.java:21)


Being this the input:

Type random numbers: 246, 421, 123, 2


EDITED: Solved. This is the code:

import java.util.Arrays;
import java.util.Scanner;

public class StartingPoint {
public static void main(String[] args) {

Scanner scanner = new Scanner(System.in);
System.out.println("Numbers: ");
String input = new String(scanner.nextLine());
scanner.close();
String[] numbers = input.split("\\D+");
int[] num = new int[numbers.length];
int i = 0;
for (String value : numbers) {
num[i] = Integer.parseInt(value);
i++;
}
Arrays.sort(num);
i = 0;
System.out.println("Sorted numbers: ");
for (int value : num) {
if (i == num.length - 1) {
System.out.println(value + ".");
} else {
System.out.print(value + ", ");
i++;
}
}

}
}


Thank you all!

Answer

I'm answering by providing an alternative that works:

System.out.println( Arrays.stream(input.split("\\D+"))
  .map(Integer::parseInt)
  .sorted()
  .map(String::valueOf)
  .collect(Collectors.joining(", ", "", ".")));

And it's only 1 line.


By popular demand, here's how it works:

  • input.split("\\D+") returns String[] of numbers, which are separated by non numbers - \D means "non digit" and \D+ means one or more non-digits
  • Arrays.stream() creates a stream from an array
  • map(Integer::parseInt) turns each String from the split into an Integer. This is needed so the next step will sort in numerical order, not lexographical order - n.b. 10 > 2 but "10" < "2"
  • sorted() sorts the stream (of Integers)
  • collect() combines the stream to a single object. See next point for how
  • Collectors.joining(", ", "", ".") is a pre-canned collector that produces a String from the stream, joining them with parameter 1 as the separator, prefix of the parameter 2 and suffix of parameter 3