将所有输入字符的出现位置移动到字符串末尾并返回新字符串

4

我需要返回一个新的字符串,其中所有输入字符的出现都被移到字符串的末尾。我尝试将给定的字符与提供的字符串进行比较,但无法获得预期的输出。

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;
}

期望输出: "heoll"

实际输出: ""heooo"


2
什么是调试器,它如何帮助我诊断问题? - Andreas
我无法理解你的策略。而且使用变量名为 m 也没有帮助。这是我的策略:对于每个字符,如果它不是给定的字符,则将其附加到字符串中。否则,增加一个计数器。完成后,将给定的字符附加多次,次数为计数器的值。 - JB Nizet
您需要提供有关如何调用函数的更多信息。例如,展示一个可以实现此功能的小型主函数。 - GS - Apologise to Monica
3个回答

5

我建议您首先使用toCharArray()将字符串作为char数组获取,对该数组进行操作,然后使用new String(charArray)将其转换回字符串。

您应该通过将所有不是c的字符复制到下一个位置来操作该数组。当首先将字符复制到它们已经存在的位置时,这样做更容易。在没有要复制的字符时,您就知道结果的其余部分必须都是c字符。

以下是一种简洁的方法:

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);
}

逐步演示循环的每个迭代:

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

1
不错的解决方案。它是一个紧凑的解决方案,但我不确定它的可读性。 - Eran
@Eran 我本来没有打算给 OP 提供代码。起初,我只是留了一个评论,其中包含了前两段的文字。但既然你提供了代码,我想我可以提供一个“更好”的(至少在性能方面)解决方案,然后将其压缩,这样 OP 就必须思考一下,不能直接提交作业而不解释它是如何工作的。 - Andreas
@Zabuza 不用了,我的紧凑代码不使用不必要的大括号。 - Andreas
通常人们在发布答案时倾向于遵循官方的风格指南。我特别关注for,这可能会给任何初学者带来问题。 - Zabuzard
@Zabuza,你指的是哪个官方风格指南? - Andreas

2
另一种方法是创建一个与字符串相同长度的新空数组,例如char [] temp = new char [word.length()],并根据字符是否等于所选字符,从两侧填充它。 类似于这样:
[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

当你完成后,可以通过new String(charArray)char[]转换为字符串。
目前我不打算给你代码,请尝试自己编写。
如果你无法编写,请查看以下提示:
你需要两个变量来表示左侧和右侧的索引,这些索引是字符应该放置的位置,具体取决于它们是否等于用户选择的字符。
不要忘记在将字符放置到它们指向的索引处后更新这些变量(向前或向后移动)。

2

你没有将给定字符移位,而是将其删除 - 用最后一个字符替换它。

你应该计算需要移位的字符数,并在最后进行移位:

而不是移动给定的字符,您正在消除它 - 您将其替换为最后一个字符。

您应该计算需要移动的字符数,并在最后移动它们:

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;
}

顺便提一下,最好使用StringBuilder实例来追加字符,而不是使用创建新String实例的String拼接。

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();
}

我建议你用 char[] 来代替。 - Andreas
1
@Andreas 那也可以工作。 - Eran

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接