4

I have to return a new string with all the occurrences of input character shifted to the end. I tried to compare the given character by the string provided but not able to get the expected output.

public String moveChar(String str, char c) {
    int len=str.length();
    String newstr="";
    int m=len-1;
    for (int i=0; i<len; i++) {
        char ch1=str.charAt(i);
        char ch2=str.charAt(m);
        if (ch1==c) {
            newstr=newstr+ch2;
        }
        else {
            newstr=newstr+ch1;
        }
    }
    return newstr;
}

Expected Output: "heoll"

Actual Output: ""heooo"

Zoe
  • 27,060
  • 21
  • 118
  • 148
  • 2
    [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/q/25385173/5221149) – Andreas Aug 18 '19 at 08:20
  • I can't understand your strategy. And the usage of variables named `m` doesn't help. Here's what my strategy would be: for each char, if it's not the given character, then append it to the string. Otherwise, increment a counter. Once done, append the given character as many times as the counter. – JB Nizet Aug 18 '19 at 08:21
  • You need to provide more information about how you're calling the function. E.g. show a small main function that does it. – Ganesh Sittampalam Aug 18 '19 at 09:10

3 Answers3

5

I recommend you start by getting the string as a char array using toCharArray(), manipulate the array, then turn it back into a string using new String(charArray).

You should manipulate the array by copying all characters that are not c to the next position. Sure, at first you're copying the chars to where they already are, but it's easier that way. When out of characters to copy, You know rest of the result has to be all c characters.

Here is a compact way to do it:

public static String moveChar(String str, char c) {
    char[] buf = str.toCharArray();
    for (int i = 0, j = 0; j < buf.length; i++)
        if (i >= buf.length)
            buf[j++] = c;       // fill
        else if (buf[i] != c)
            buf[j++] = buf[i];  // copy
    return new String(buf);
}

Illustrated, step by step, each iteration of the loop:

H e l l o     i = 0, j = 0
│             copy: buf[j++] = buf[i]; i++
↓
H e l l o     i = 1, j = 1
  │           copy: buf[j++] = buf[i]; i++
  ↓
H e l l o     i = 2, j = 2
              skip: i++

H e l l o     i = 3, j = 2
              skip: i++

H e l l o     i = 4, j = 2
    ┌───┘     copy: buf[j++] = buf[i]; i++
    ↓
H e o l o     i = 5, j = 3
              fill: buf[j++] = c; i++
      ↓
H e o l o     i = 6, j = 4
              fill: buf[j++] = c; i++
        ↓
H e o l l
Andreas
  • 154,647
  • 11
  • 152
  • 247
  • 1
    Nice solution. It is a compact solution, but I'm not sure about its readability. – Eran Aug 18 '19 at 08:48
  • @Eran I hadn't intended to give code to OP. At first, I left a comment with the text from the first two paragraphs. But since you gave code, I thought I'd give a "better" (for performance anyway) solution, then made it compact so OP would have to think about it, i.e. couldn't submit the code as-is as homework without being able to explain how it worked. – Andreas Aug 18 '19 at 08:53
  • @Zabuza No thanks. My *compact* code doesn't use unnecessary braces. – Andreas Aug 18 '19 at 17:03
  • Usually people tend to follow the official style guide when posting answers. Im especially concerned about the `for`, this will likely yield to issues for any beginner. – Zabuzard Aug 18 '19 at 18:44
  • @Zabuza Which ***the*** official style guide are you referring to? – Andreas Aug 19 '19 at 00:24
2

Instead of shifting the given character, you are eliminating it - you replace it with the last character.

You should count the number of characters you need to shift, and shift them at the end:

public String moveChar(String str, char c) {
    int len=str.length();
    String newstr="";
    int count=0;
    for (int i=0; i<len; i++) {
        char ch1=str.charAt(i);
        if (ch1==c) {
            count++;
        } else { // append only the characters that don't require shifting
            newstr=newstr+ch1;
        }
    }
    for (int i = 0; i < count; i++) { // append the characters that require shifting 
                                      // at the end
        newstr=newstr+c;
    }
    return newstr;
}

BTW, it would be better to use a StringBuilder instance to append the characters instead of using String concatenation that creates a new String instance.

public String moveChar(String str, char c) {
    int len=str.length();
    StringBuilder newstr=new StringBuilder(len);
    int count=0;
    for (int i=0; i<len; i++) {
        char ch1=str.charAt(i);
        if (ch1==c) {
            count++;
        } else { // append only the characters that don't require shifting
            newstr.append(ch1);
        }
    }
    for (int i = 0; i < count; i++) { // append the characters that require shifting 
                                      // at the end
        newstr.append(c);
    }
    return newstr.toString();
}
Eran
  • 387,369
  • 54
  • 702
  • 768
2

Another approach could be creating new empty array of same length as string like char[] temp = new char[word.length()], and filling it from both sides depending on if character is equal or not to selected one.

Something like:

[iteration] -> [result array]

hello -> h????   // h != l 
^        ^       // so we add it from left
i        L

hello -> he???   // e != l 
 ^        ^      // so we add it from left
 i        L

hello -> he??l   // l == l 
  ^          ^   // so we add it from right
  i          R

hello -> he?ll   // l != l
   ^        ^    // so we add it from right
   i        R

hello -> heoll   // o != l
    ^      ^     // so we add it from left
    i      L

When you are done you can covert char[] to sting via new String(charArray).

For now I am not going to give you the code, try to write it yourself.

If you will not be able to write it take a look at below hints:

You will need two variables representing left and right index at which characters should be placed, depending if they ware equal or not to character selected by user.

 

Don't forget to update those variables (move it forward, or backward) after placing character at index they ware pointing.

Pshemo
  • 122,468
  • 25
  • 185
  • 269