【问题标题】:if(s1.Contains(s2)) Seems to always be trueif(s1.Contains(s2)) 似乎总是正确的
【发布时间】:2017-02-10 06:47:50
【问题描述】:

抱歉,问题稍微改了一下。

基本上我想知道aString 是否包含String。我的问题是当比较 aS aString) "aS".contains("String") 的子字符串时显示为真。

String a="st", b="string"; 我跑了System.out.println(a.contains(b)); 正如预期的那样,返回了false。我对包含有所了解,我一定是遗漏了其他东西。

所以看起来我的程序运行正常,但我做了一些调整然后回来,整个事情就停止了。我找出了常见的罪魁祸首(brackets, file io, etc.)。我发现if(string.contains(string)) 会不断运行,即:总是正确的。不知道为什么会这样,可能是我在代码中遗漏了一些东西。

这是我的输出示例(只是逐字符读取文件):

I n t e g e r G ;

import java.io.File;
import java.util.ArrayList;
import java.util.Scanner;

public class comp{

    public static void main(String[] args){
        ArrayList<String> lines = new ArrayList<String>();
        ArrayList<String> symbolTable = new ArrayList<String>();
        ArrayList<String> parsedFile = new ArrayList<String>();


         try {
                File file = new File("symbolTable.txt");
                Scanner scanner=new Scanner(file);
                while (scanner.hasNextLine()&&symbolTable.add(scanner.nextLine().replaceAll("\\s+","").toLowerCase()));
                scanner.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }


         try {
                File file = new File("APU_CS400_input.txt");
                Scanner scanner=new Scanner(file);
                while (scanner.hasNextLine()&&lines.add(scanner.nextLine().replaceAll("\\s+","").toLowerCase()));
                scanner.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }


         //runs through line by line of the input file
         for(String line: lines){
             String sBuild = "";
             StringBuilder identifier = new StringBuilder("");

             //moves through the line char by char
             for(int i=0;line.length()>i; i++){
                 sBuild+=line.charAt(i);
                 //moves through the symbol table comparing each symbol to each string 
                 //that is built char by char
                 for(String symbol: symbolTable){
                     //if the char string matches the symbol then any identifiers are saved and 
                     //symbols are saved, the string is then reset to empty
            //This is where i seem to get an issue

        ***if(sBuild.contains(symbol)){***
                        if(symbol.length()<sBuild.length()){
                            identifier.append(sBuild,0,sBuild.length()-symbol.length()); 
                            parsedFile.add(identifier.toString());
                            identifier.delete(0,sBuild.length()-symbol.length());
                        }
                        sBuild="";
                        parsedFile.add(symbol);
                     }

                 }
             }
         }


         for(String symbol:parsedFile){
             System.out.println(symbol);
         }

    }

}

Blockquote 

【问题讨论】:

  • 为什么不是真的?
  • 确实,它总是应该是真的。
  • “抱歉,稍微改变了问题”——这是一个错字,应该写成“抱歉,把问题彻底改成了完全不同的东西”。
  • 如果 sBuild.contains(symbol) 在您认为应该为 false 时返回 true,则可能 sBuild 和/或 symbol 不是您认为的值。这就是 debugging 用于找出问题所在的地方。 你应该试试!

标签: java string contains


【解决方案1】:

if(String.Contains("")) 总是应该为真,只要字符串不为空。

【讨论】:

  • 对,虽然有点脱离上下文,但我重新表述了我的问题以使其更有意义。
  • @user3674515:断章取义?您的问题标题完全无聊。
【解决方案2】:

这样想。

s1.contains(s2)

如果可以找到s1 的子字符串,则应返回true

s1.substring(i, j).equals(s2)

是真的。

如果s2 是一个空字符串,那么i = 0, j = 0 就是一个这样的子字符串,所以contains() 返回true

应该的。

【讨论】:

  • "st".contain("string") 会是真的吗?
  • @user3674515 当然不是。你能找到一个等于"string""st" 的子串吗?没有。
【解决方案3】:

您可能需要从数学角度看一下为什么s.contains("") 总是正确的。假设你这样想:

如果ij 的某些值使得a.substring(i,j) 等于b,则a.contains(b) 为真。

如果您稍微考虑一下,您会发现这正是contains 在参数是像"xyz" 这样的非空字符串时的含义。如果有一些substringx 等于"xyz",则s.contains("xyz") 为真。如果没有这样的子字符串,则s.contains("xyz") 为假。

因此,相同的逻辑适用于空字符串是有道理的,因为它适用于其他任何地方。 a.substring(0,0) 等于 "" 总是正确的(如果 a 不为空)。这就是为什么a.contains("") 应该始终为真。

从“包含”的英文含义可能并不直观,但是当您处理这样的“边缘情况”时,您有时必须以不同的方式思考。通常,Javadoc 会详细说明,这样您就可以轻松地弄清楚在边缘情况下会发生什么,而无需依赖直觉。不幸的是,在这种情况下,他们没有。

【讨论】:

  • 不,在我发布这个之前我没有看到 Andreas 的回答,尽管我们只是碰巧使用了相同的索引变量名称。我认为“伟大的思想都一样”适用于这里...... :) :)
  • 对,空字符串总是匹配的。我的问题(已修改)是为什么当我有一个字符串 a="I" 和字符串 b="integer" 时,我说 a.contains(b) 会导致 true。
  • 你不应该那样修改你的问题。可以修改问题以提供更多信息或纠正错误或改进措辞或格式。但是,当您在人们发布答案后将其更改为完全不同的问题时,您会使回答者看起来像白痴。这不是对待那些自愿花时间提供帮助的人的好方法。如果您有其他问题,请发布其他问题。
  • 我很抱歉,下次会记住这一点。没想到在我写的内容之外,仅标题就有这么多答案。
  • @user3674515 你现在正在编程。你应该习惯你写的东西很重要的事实。因为它在编写代码时会发生。如果你写错了部分代码,你将不会得到你想要的结果。就像这个问题发生的一样。你没有正确写出问题,所以你没有得到可以帮助你的答案。 在编程中,你写的东西很重要。 在现实生活中也是如此,但人们比计算机更宽容。学会精确。
【解决方案4】:

基本上我想知道“aString”是否包含“String”。

是的,"aString" 作为字符串值确实包含"String" 的字符串值

我的问题是当比较说“aS”(“aString”的子字符串)时,“aS”.contains("String") 显示为真。

你确定吗?这不可能,因此我宁愿怀疑您的代码中存在错误。


为了避免“空字符串符号”,考虑一下:

try {
  File file = new File("symbolTable.txt");
  Scanner scanner=new Scanner(file);
  while (scanner.hasNextLine()) {
    // toLowerCase will do nothing for characters that are not letters
    // Don't spend CPU cycles with regex
    String symbolLine=scanner.nextLine().toLowerCase();
    // Collect the symbol only if non-empty?? This will save you from empty symbols
    if(symbolLine.trim().length()>0) {
      symbolTable.add(symbolLine); // or .add(symbolLine.trim()) ???
    }
  }
  scanner.close();
} catch (Exception ex) {
  ex.printStackTrace();
}

【讨论】:

  • 听取了您的建议并引导我找到答案,我没有考虑文件末尾的换行符。男人很沮丧,并在我编辑符号表之前解释了它为什么会起作用。谢谢!
  • 您提到正则表达式是一种删除空格的缓慢方法,所以我选择了修剪。对于删除“/n”,您有什么建议?因为我目前正在使用正则表达式 .replace("\n", "")。
  • @user3674515 trim 也会处理\n - 阅读trim javadoc - 从字符串的开头和结尾删除小于或等于0x20(空格)的任何内容。 \n0x0A
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-12
  • 2013-08-02
  • 1970-01-01
相关资源
最近更新 更多