Alfie
Alfie

Reputation: 2013

How to add a space between every int and non-int value?

I would like to add a space between every number and non-number in a string, and also between each non-number.

For example: "133+23d-=" ➟ "133 + 23 d - ="

Here is my attempt:

for(int i=0; i<input.length();i++){
    if((Character.isDigit(input.charAt(i)) && !Character.isDigit(input.charAt(i+1))) || (!Character.isDigit(input.charAt(i)) && Character.isDigit(input.charAt(i+1))) || (!Character.isDigit(input.charAt(i)) && !Character.isDigit(input.charAt(i+1)))){
        input = input.substring(0, i) + " " + input.substring(i, input.length());
    }   
}

(where "input" is the string I want to do this to)

Currently the loop just loops infinity for some reason??

Upvotes: 0

Views: 4149

Answers (5)

Serge Ballesta
Serge Ballesta

Reputation: 148965

The problem here is that you insert one position before. Let's do it by hand:

  • i=0 : process 1 and 3 - both digits nothing is changed
  • i=1 : process 3 and 3 - both digits nothing is changed
  • i=2 : process 3 and + - digit and no digit => add a space at position i! input becomes wrongly 13 3+23d-=. So you will continuously add spaces before the last 3 and get an infiny loop.

But that's not all, even if you fix it with:

input = input.substring(0, i+1) + " " + input.substring(i+1, input.length());

and get correctly 133 +2d-= things will still break:

  • i=3: process (space) and + => both are not digits and you still add a space.

Here again you get an infinite loop adding spaces before the +.

Hell is hidden in details! After adding a space, you must skip it, and you must stop one position before last because you later use input.charAt(i+1).

Your fixed code becomes:

    for (int i=0; i<input.length() - 1; i++) {
        if ((Character.isDigit(input.charAt(i)) && !Character.isDigit(input.charAt(i + 1))) || (!Character.isDigit(input.charAt(i)) && Character.isDigit(input.charAt(i + 1))) || (!Character.isDigit(input.charAt(i)) && !Character.isDigit(input.charAt(i + 1)))) {
            input = input.substring(0, i+1) + " " + input.substring(i+1, input.length());
            i += 1;
        }
    }

TL/DR: all that would have been self evident if you had simply run the loop under a debugger. Eclipse of Netbeans both include a nice one.

But that's not all. You are repeatedly re-assigning the input String. Even if low case optimizations should be avoided in early development stages, this is bad. It would be cleaner to browse the input string, adding original chars and spaces into a StringBuilder and only at the end extract the resulting String from the StringBuilder.

Upvotes: 0

Andrei Rusu
Andrei Rusu

Reputation: 46

I would like to add a space between every number and non-number in a string.

For example: "133+23d-=" ➟ "133 + 23 d - ="

As you described the problem, I think the result should be "133 + 23 d-=" .

Basically this should be the algorithm

        String input = "133+23d-=";
        StringBuilder result = new StringBuilder();
        boolean number = false;
        for( int i = 0; i < input.length(); i++ ){
            if( input.charAt(i) < '0' || input.charAt(i) > '9' ){ // not a digit
                if( number ){
                    result.append(" ");
                }
                number = false;
            }else{
                if( !number ){
                    result.append(" ");
                }
                number = true;
            }
            result.append(input.charAt(i));
        }

        System.out.println(result.toString());

Upvotes: 0

castletheperson
castletheperson

Reputation: 33486

You can use regex to detect the positions before and after a non-digit character \\D.

String input = "133+23d-=";
String output = input.replaceAll("(?<=\\D)|(?=\\D)", " ");
// '133 + 23 d - = '

Ideone Demo

Upvotes: 2

cokceken
cokceken

Reputation: 2076

You can use regex.

String s = "133+23d-=";
s = s.replaceAll("(\\d+)", "$1 "); //finds every consecutive digits and puts a space after them
s = s.replaceAll("([-a-zA-Z]+)", "$1 "); //finds every consecutive characters and puts a space after them

Upvotes: 1

Crusha K. Rool
Crusha K. Rool

Reputation: 1502

You are reassigning input in the loop and extending its length, while also using the length as a condition to terminate on. So you will also take the newly added whitespace into account, which will trigger yet another whitespace to be inserted, etc.

Instead of directly modifying the input, you should store the result in a separate variable (ideally a StringBuilder, for performance reasons).

Also, since your i is running from 0 to length-1, you will get an IndexOutOfBoundsException when trying to access charAt(i+1) in the last iteration of that loop.

Upvotes: 4

Related Questions