TransWikia.com

Problem with even indexes in Java program

Stack Overflow Asked by ioThio on January 1, 2022

The method takes 2 parameters (String,char) and returns the string with the char replaced by '+' if index is even and '#' if index is odd.

The String I use is "Mary Bella Abracadabra" and the expected output is "M+ry Bell+ +br#c#d#br+". Instead I get "M#ry Bell# #br#c#d#br#".

I can’t find the error in my code. It seems that all indexes where char ch is found are odd.

public String emphasize (String phrase, char ch){
    String phraseEmph = "";
    char c1 = '#';
    char c2 = '+';
    for (int i=0; i < phrase.length(); i++){
         char c = phrase.charAt(i);
         char cc = Character.toLowerCase(c);
         if ((cc == ch) && ((i % 2) == 0)){
            phraseEmph = phrase.replace(c,c2);
            phrase = phraseEmph;   
            }
         else if ((cc == ch) && ((i % 2)!= 0)){
            phraseEmph = phrase.replace(c,c1);
            phrase = phraseEmph;   
            }  
         phrase = phrase; 
    }
    return phrase;
}

public void testEmphasize(){
    String phrase = "Mary Bella Abracadabra";
    char ch = 'a';
    String Emphasized = emphasize(phrase,ch);
    System.out.println("Emphasized : " + Emphasized);
}

6 Answers

Full tested simplified code :

public class Main {
    public static void main(String[] args) {
        String phrase = "Maryaa Bella Abracadabra";
        char ch = 'a';
        System.out.println("Original   : " + phrase);
        String Emphasized = emphasize(phrase,ch);
        System.out.println("Emphasized : " + Emphasized);
    }
    
    public static String emphasize (String phrase, char ch){
        StringBuilder temp = new StringBuilder(phrase); 
        char c1 = '#';
        char c2 = '+';
        for (int i = 0; i < phrase.length(); i++){
             char c  = phrase.charAt(i);
             char cc = Character.toLowerCase(c);
             if(cc == ch) {
                 if(i%2 == 0){
                     temp.setCharAt(i, c1);
                 } else {
                     temp.setCharAt(i, c2);
                 }
             }
        }
        return temp.toString();
    }
        
}

Output :

Original   : Maryaa Bella Abracadabra                                                                                                                          
Emphasized : M+ry#+ Bell+ +br#c#d#br+

Answered by Som on January 1, 2022

  1. Use StringBuilder instead of String for concatenation to a string inside a loop because it is much faster and consumes less memory.
  2. Convert both the characters in the same case (e.g. lowercase) before comparing. This way, you can pass the character to the function in any case.
  3. You should not use String#replace for this case as it replaces all occurrences of replacement character/string in the string being replaced.

Demo:

public class Main {
    public static void main(String[] args) {
        // Test
        System.out.println(emphasize("Mary Bella Abracadabra", 'a'));
        System.out.println(emphasize("Mary Bella Abracadabra", 'A'));
    }

    public static String emphasize(String phrase, char ch) {
        char c1 = '#';
        char c2 = '+';
        StringBuilder sb = new StringBuilder();

        // Convert the char parameter to lower case
        char chLower = Character.toLowerCase(ch);

        for (int i = 0; i < phrase.length(); i++) {
            char c = phrase.charAt(i);
            if (Character.toLowerCase(c) == chLower) {
                if (i % 2 == 0) {
                    sb.append(c1);
                } else {
                    sb.append(c2);
                }
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }
}

Output:

M+ry Bell+ +br#c#d#br+
M+ry Bell+ +br#c#d#br+

Answered by Arvind Kumar Avinash on January 1, 2022

Here are some suggestions.

  • use a StringBuilder to make the character replacements. Intialize to the original string. You can then use setCharAt to make the change.
  • Use indexOf in conjunction with toLowerCase. Then you don't need to verify if you found the character, just use the index returned and return the final string if -1.
  • then just check for even or or indices like you are doing but assign to a holding char variable.
  • Then use that to replace the character. Like this pseudocode
    char repl;
    if (even) {
       repl = '#';
    } else {
       repl = '+';
    }
    make replacement
  • don't do a check for both even or odd. Just check for one condition, Otherwise it must be the other condition (not need to check again).

Aside from my recommendations, here is another way of doing it.

The main difference is that it uses the even/odd result to index into the array to replace the character.

public static String emphasize(String phrase, char ch) {
    StringBuilder sb = new StringBuilder(phrase);
    char[] chars = { '#', '+' };
    int idx = -1;
    while ((idx = phrase.toLowerCase().indexOf(ch, idx + 1)) >= 0) {
        sb.setCharAt(idx, chars[idx % 2]);
        phrase = sb.toString();
    }
    return phrase;
}    

Answered by WJS on January 1, 2022

Your code is very inefficient, my suggestion :

class emphasize {
    private String phrase;
    private char ch;
    public emphasize(String phrase, char ch) {
        this.phrase = phrase;
        this.ch = ch;
    }
    public String execute() {
        char chars[] = phrase.toCharArray();
        for (int i = 0 ; i < chars.length ; i++) {
            /* As char is primitive type I can use == */
            if (chars[i]==Character.toLowerCase(ch) || chars[i]==Character.toUpperCase(ch)) chars[i] = i%2==0 ? '+' : '#';
        }
        return String.valueOf(chars);
    }
}
public class Main {
    public static void main(String[] args) {
        String phrase = "Mary Bella Abracadabra";
        char ch = 'a';
        emphasize obj = new emphasize(phrase, ch);
        System.out.println(obj.execute());
    }
}

Output :

enter image description here

Answered by Shiv Patel on January 1, 2022

Note Array start with 0 in java. String is immutable and don't provide many mutable methods. It's best to make use of StringBuilder as shown below both for easiness and memory efficiency.

    public static String emphasize(String phrase, char ch) {
    StringBuilder phraseEmph = new StringBuilder(phrase);
    char c1 = '#';
    char c2 = '+';
    for (int i = 0; i < phrase.length(); i++) {

        char c = phrase.charAt(i);
        char cc = Character.toLowerCase(c);
        if ((cc == ch) && ((i % 2) == 0)) {
            phraseEmph.setCharAt(i, c2);
        } else if ((cc == ch) && ((i % 2) != 0)) {
            phraseEmph.setCharAt(i, c1);
        }
    }
    return phraseEmph.toString();
}

Answered by SauriBabu on January 1, 2022

When you call replace it doesn't just replace the current 'a', it replaces all of them. You'll need to find a different way to replace characters so that you only change one at a time.

(I've purposefully avoided suggesting a fix. It'll be more educational if you come up with it yourself.)

Answered by John Kugelman on January 1, 2022

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP