对于字符串长度的循环奇怪地跳过一些字符

for loop on String length weirdly skipping some chars

如标题所述,我在从文件中读取的字符串上进行 运行 for 循环,试图删除每个 - 字符,但奇怪的是删除了一些字符并跳过了其他字符。 这是正在处理的字符串:

这是我的职能:

        System.out.println(newSeq);
        System.out.println(" String before deleteing -  = " +newSeq + "   length  = " + newSeq.length());
        for (int i = 0; i < newSeq.length(); i++) {
            System.out.println("char at : " + i + " = " + newSeq.charAt(i) );
            // Delete every -
            if ( newSeq.charAt(i) == '-'){
                StringBuilder lineString = new StringBuilder(newSeq);
                lineString.deleteCharAt(i);
                newSeq = lineString.toString();
            }
        }
        System.out.println("String after deleting -  = " + newSeq);

输出:

如果你不需要重新发明轮子,Java已经有replace方法:

newSeq = newSeq.replace("-", "");

首先,值得一提的是,您正在迭代一个字符数组,然后循环更改它。

如果不深入研究这个问题,我猜你的结果字符串中发生的事情只删除了最后一个 -,因为对象 re-assigning 完成了在循环中。

为了正确完成此任务,您需要使用新变量或对字符串使用 .replace 方法,这会将每个找到的字符或字符串的一部分替换为另一个。

为了使其正确,仍然使用 for 循环我建议您创建一个名为 result 的新字符串,然后将其与允许的字符连接:

String result = "";
for (int i = 0; i < newSeq.length(); i++) {
    if ( newSeq.charAt(i) != '-'){
        // this character is allowed, add it to the result
        result += newSeq.charAt(i);
    }
}
      // Delete every -
        if ( newSeq.charAt(i) == '-'){
            StringBuilder lineString = new StringBuilder(newSeq);
            lineString.deleteCharAt(i);
            newSeq = lineString.toString();
        }

这段代码有问题。您正在删除一个字符并再次重新分配缩短的长度字符串。所以删除后右手字符的位置会向左移动一位。所以你会得到不可预测的结果。

将其放入 StringBuilder 中并从末尾开始删除。这样你的索引就不会不同步。如果你从头开始,你会错过相邻的字符。当然,这只是解决了您选择的方法的问题。使用String.replace()是最简单的方法。

String newSeq = "UCGU----ACAGU";
System.out.println(newSeq);
StringBuilder sb = new StringBuilder(newSeq);
for (int i = sb.length() - 1; i >= 0; i--) {
    if (sb.charAt(i) == '-') {
        sb.deleteCharAt(i);
    }
}
newSeq = sb.toString();

System.out.println(newSeq);

版画

UCGUACAGU

你可以使用.replaceAll()方法,像这样:

public static void main(String[] args) {
    
    String newSeq = "UCGU---AGAGU";
    
    System.out.println(newSeq);
    
    System.out.println("String before deleting '-': " + newSeq + ", length: " + newSeq.length() + "\n");
    
    for (int i = 0; i < newSeq.length(); i++) {
        System.out.println("Char at " + i + ": " + newSeq.charAt(i));            
    }
    
    newSeq = newSeq.replaceAll("-", "");
    
    System.out.println("\nString after deleting '-': " + newSeq);
}

您遇到问题是因为您在循环中更改了 newSeq。

假设输入为:“1--3”。在第二次迭代中,char 将为 -。然后你将用“1-3”替换输入。索引为 2 的下一个第三次迭代将尝试检查第三个字符,但第三个字符将为 3。

你可以用 replace:

    input.replace("-", "")

或使用正则表达式:

    input.replaceAll("-+", "")

或循环:

    var input = "1--3";
    StringBuilder lineString = new StringBuilder();
    for (char item : input.toCharArray()) {
        if (item != '-'){
            lineString.append(item);
        }
    }
    System.out.println(lineString.toString());

或流:

    var input = "1--3";
    var output = Arrays.stream(input.split(""))
            .filter(character -> !character.equals("-"))
            .collect(Collectors.joining());
    System.out.println(output);