字符串长度的for循环奇怪地跳过了一些字符

Posted

技术标签:

【中文标题】字符串长度的for循环奇怪地跳过了一些字符【英文标题】:for loop on String length weirdly skipping some chars 【发布时间】:2021-06-29 08:53:26 【问题描述】:

如标题中所述,我正在从文件中读取的字符串上运行 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);

输出:

【问题讨论】:

Remove all occurrences of char from string 【参考方案1】:

将其放入 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

【讨论】:

【参考方案2】:

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

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

你可以用替换来做到这一点:

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

【讨论】:

很有意义我忘记了,当我删除一个字符时,长度()会减少而计数器正在增加^^'谢谢【参考方案3】:

你可以使用.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);

【讨论】:

【参考方案4】:

如果你不需要重新发明***,Java 已经有一个replace 方法:

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

【讨论】:

首先是 replace('-', '\0');并替换('-','');其次,我有点需要在循环中执行它,因为我需要跟随计数器,因为我还试图从其他字符串中删除与 - 相同位置的字符,所以实际上当它进入 if 函数时我使用i 光标从两个字符串中删除 @4212 replace('-', '\0')- 替换为空字符 \0replace('-', '') 是无效的 Java,因为 '' 不是字符。 replace("-", "") 通过将 - 替换为空字符串来删除所有 - 字符。【参考方案5】:
      // Delete every -
        if ( newSeq.charAt(i) == '-')
            StringBuilder lineString = new StringBuilder(newSeq);
            lineString.deleteCharAt(i);
            newSeq = lineString.toString();
        

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

【讨论】:

【参考方案6】:

首先,值得一提的是,您正在迭代一个字符数组,然后您将在循环中对其进行更改。

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

为了正确执行此任务,您需要使用新变量或对字符串使用.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);
    

【讨论】:

以上是关于字符串长度的for循环奇怪地跳过了一些字符的主要内容,如果未能解决你的问题,请参考以下文章

VBA - 如何有条件地跳过for循环迭代

如何有条件地跳过python中for循环中的迭代步骤数?

长阵列性能问题

如何在批处理文件中的for循环中使用可变长度的子字符串?

while循环创建用户(区别for)

PHP for循环中怎么让字符串超过固定特定长度后自动换行?