How do I replace characters from a string, right to left, cumulatively?

Asked

Viewed 81 times

1

I’m trying to write a function that gets a String and replaces its characters from right to left, for zero. I would also like to do this cumulatively and save the changes. For example:

String teste = "12345678"

When I iterate for her, I’d like the result to be:

  • "12345670"
  • "12345600"
  • "12345000"
  • "12340000"... and so on.

The code I wrote so far:

public String test = "12345678";

public String replaceFromRightToLeft(String test) {
    for (int i = test.length() -1; i >= 0; i--) {
        test.replace(test.charAt(i), '0');
    }
    return test;
}

However, when I run, I get the results as follows:

  • 12345670
  • 12345608
  • 12345078
  • 12340678
  • 12305678
  • 12045678
  • 10345678
  • 02345678

Therefore, what I need to do to "save" the changes cumulatively?

2 answers

4


In Java, String's are immutable, then methods that "alter" the String in fact return another String containing the changes. Therefore, you should take the return of replace and assign to variable test:

public String replaceFromRightToLeft(String test) {
    for (int i = test.length() -1; i >= 0; i--) {
        test = test.replace(test.charAt(i), '0');
        System.out.println(test); // imprime o resultado parcial
    }
    return test;
}

If you just do test.replace(test.charAt(i), '0') (without assigning to any variable), the return of replace - which is the String modified - is ignored and "lost".

Using the code above and calling replaceFromRightToLeft("12345678"), the result will be:

12345670
12345600
12345000
12340000
12300000
12000000
10000000
00000000

But there’s a catch: replace replaces all the occurrences of the character, then if the String for example, "1234321", the result will be:

0234320
0034300
0004000
0000000
0000000
0000000
0000000

That’s because on the first call, she replaces all the characters 1 for 0 (that is, exchanges both the first and the last 1), and the same thing for the 2, 3, etc..

So if the idea is to trade only the last character (and then only the penultimate, and only the antepenultimate, etc., whether or not the character is repeated in the String), I suggest not to use replace. An alternative is to iterate through the array of char of own String and keep changing him:

public String replaceFromRightToLeft(String test) {
    char[] chars = test.toCharArray();
    for (int i = chars.length-1; i >= 0; i--) {
        chars[i] = '0';
        System.out.println(new String(chars)); // imprime o resultado parcial
    }
    return new String(chars); // retorna a String final
}

Or use a StringBuilder (this yes changeable, can be changed at will):

public String replaceFromRightToLeft(String test) {
    StringBuilder sb = new StringBuilder(test);
    for (int i = sb.length() - 1; i >= 0; i--) {
        sb.setCharAt(i, '0');
        System.out.println(sb.toString()); // imprime o resultado parcial
    }
    return sb.toString();
}

Testing both of the above options with "1234321" the result is:

1234320
1234300
1234000
1230000
1200000
1000000
0000000
  • 1

    Gee!! What a sensational explanation! Thank you so much @hkotsubo!!

2

If you take a look at the description of replace you will see that it has a return. However in your code you are never assigning it. What you should do is this:

public String test = "12345678";
    
    public String replaceFromRightToLeft(String test) {
        for (int i = test.length() -1; i >= 0; i--) {
            test = test.replace(test.charAt(i), '0');  //atribui retorno do replace a sua string test
        }
        return test;
    }

Browser other questions tagged

You are not signed in. Login or sign up in order to post.