我试图了解这段代码中子字符串调用的工作方式?

时间:2019-06-01 12:18:50

标签: java substring indexof

我知道子字符串的工作原理,但是我试图在下面的代码中了解它的工作原理。目的是在字符串数组中找到最长的公共前缀。字符串输入为{flower,flow,fleece}。看起来子串每次都只花整个单词,当它不为0时,每次,因为length-1的0将给出整个单词。

 public String longestCommonPrefix(String[] strs) {
    if (strs.length == 0) return "";
    String prefix = strs[0];
    for (int i = 1; i < strs.length; i++)
        while (strs[i].indexOf(prefix) != 0) {
            prefix = prefix.substring(0, prefix.length() - 1);
            if (prefix.isEmpty()) return "";
        }        
    return prefix;
}

输出是fl。我只是想了解原因。

3 个答案:

答案 0 :(得分:1)

  

长度为1的0将给出整个单词


不,它返回除最后一个字符以外的单词。
发件人:https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#substring(int,%20int)

  

public String substring(int beginIndex,int endIndex)
返回一个   作为此字符串的子字符串的新字符串。
子字符串   从指定的beginIndex开始,并扩展到位于的字符   index endIndex-1.

因此,代码要做的是用此行修剪每次迭代中的最后一个字符:

prefix = prefix.substring(0, prefix.length() - 1);

直到找到通用前缀。

答案 1 :(得分:1)

substring()中的endIndex是排他的。因此,代码要做的是从前缀变量中删除最后一个字符。

String hello = "hello";
System.out.println(hello.substring(0,hello.length));
// hello
System.out.println(hello.substring(0,hello.length - 1));
// hell

答案 2 :(得分:0)

虽然这不是您直接要问的问题,但值得一提的是,使用indexOfsubstring并不是解决此问题的好方法。

strs[i].indexOf(prefix) != 0是检查字符串是否以某些内容开头的低效方法。这是因为,如果发现字符串不是以prefix开头,它将继续搜索其他位置的出现-并不会出现在该位置。

更有效的检查是!strs[i].startsWith(prefix):一旦发现字符串不是以前缀开头,它就会停止。

然后,使用substring将字符从字符串末尾切掉也是无效的:每次将一个字符切掉,都会创建一个新的字符串,然后再次检查;但是在找到匹配的前缀之前,您可能必须先砍掉很多个单个字符。

您可以通过使用strs[i].regionMatches(0, prefix, 0, someLength)来避免这种“创建对象”的问题,其中someLength是一个以prefix.length()开头的int,然后递减直到{{1} }返回true。但这仍然效率不高,因为您一次将其递减一次。

以另一种方式进行操作会更容易:以regionMatches从零开始,然后递增直到出现以下两种情况:

  • 它等于someLength的长度:prefix
  • 它等于someLength >= prefix.length()的长度:strs[i]
  • 该位置的对应字符不匹配:someLength >= strs[i].length()

这基本上是prefix.charAt(someLength) != strs[i].charAt(someLength)的工作,但是通过“自己”完成,您可以找出字符串不同的位置。

然后,使用startsWith一次性将其切碎。或根本不切碎:您可以简单地存储公共前缀的长度,并在末尾执行一次子字符串。

代码类似于:

prefix = prefix.substring(0, someLength);