if(s1.Contains(s2)) 似乎总是正确的

if(s1.Contains(s2)) Seems to always be true

抱歉,稍微更改了问题。

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

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

所以我的程序似乎运行正常,但我做了一些调整并返回,整个程序停止运行。我猜出了通常是什么常见的罪魁祸首 (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 

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

这样想。

s1.contains(s2)

应该 return true,如果可以找到 s1 的子串使得

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

是真的。

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

理应如此。

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

a.contains(b) is true if there are some values i and j such that a.substring(i,j) is equal to b.

如果你仔细考虑一下,你会发现当参数是非空字符串(如 "xyz")时,这正是 contains 的意思。如果 x 中有 substring 等于 "xyz",则 s.contains("xyz") 为真。如果没有这样的子串,则 s.contains("xyz") 为假。

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

从"contains"的英文含义上看可能不是很直观,但是当你像这样处理"edge cases"时,你有时不得不换位思考。通常,Javadoc 会把事情说清楚,这样你就可以很容易地弄清楚在边缘情况下会发生什么,而不需要依赖直觉。不幸的是,在这种情况下,他们没有。

essentially i want to know if "aString" contains "String".

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

的字符串值

My issue is when comparing say "aS" (a substring of "aString") "aS".contains("String") shows true.

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


为了避免 "empty String symbols" 考虑这个:

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