java Codingbat挑战:sameEnds

0qx6xfy6  于 2023-04-04  发布在  Java
关注(0)|答案(4)|浏览(100)

给定来自CodingBat的任务sameEnds
给定一个字符串,返回在字符串的开头和结尾都出现的最长的子字符串。例如,sameEnds(“abXab”)是“ab”。

sameEnds("abXYab") → "ab"
sameEnds("xx") → "x"
sameEnds("xxx") → "x"

我的解决方案通过了所有测试,除了一个^:

public String sameEnds(String string) {
  String substringFront = "";
  String substringEnd = "";
  String longestSubstring = "";
  
  for (int i = 1; i < string.length() - 1; i++) {
    substringFront = string.substring(0, i);
    substringEnd = string.substring(i);
    
    if (substringEnd.contains(substringFront)) {
      longestSubstring = substringFront;
    }
  }
  
  return longestSubstring;
}

出什么问题了?我怎么才能解决?

e0uiprwp

e0uiprwp1#

除了@Dan和其他人恰当地指出的技术问题之外,我想强调不必要的复杂性问题,这在许多情况下会导致这种逻辑错误。
考虑到这一点,并考虑到这是一个挑战,我更喜欢一个简约的方法,就像下面的一个,这是不言自明的,因此易于理解和调试。

public String sameEnds(String string) {
  int middle = string.length() / 2;
  for (int i = middle; i >= 0; i--) {
    String left = string.substring(0, i);
    if (string.endsWith(left)) {
      return left;
    }
  }
  return "";
}
liwlm1x9

liwlm1x92#

你的代码中有几个问题:

  • 在到达最后一个字符之前停止迭代,而不是迭代到包含长度/2(您需要检查没有重叠的开始和结束,因此不需要迭代到结束或几乎)。
  • substringEnd应该从右侧开始,所以它看起来应该像string.substring(string.length() - i);

下面是一个固定的实现:

public static void main(String[] args) {
    List<String> listTest = List.of("abXYab", "xx", "xxx", "xxxx", "javaXYZjava", "javajava", "Hello! and Hello!", "x", "", "abcd", "mymmy");
    String substringFront, substringEnd, longestMatch;
    for (String string : listTest) {
        longestMatch = "";
        for (int i = 1; i <= string.length() / 2; i++) {
            substringFront = string.substring(0, i);
            substringEnd = string.substring(string.length() - i);

            if (substringEnd.equals(substringFront) && substringEnd.length() > longestMatch.length()) {
                longestMatch = substringEnd;
            }
        }

        if (!listTest.equals("")) {
            System.out.printf("%s => %s%n", string, longestMatch);
        } else {
            System.out.printf("%s => null%n", string);
        }
    }
}

下面是测试上面代码的链接:
https://www.jdoodle.com/iembed/v0/rEO
然而,为了使其更简洁,您可以使用正则表达式,该正则表达式使用带有贪婪量词的捕获组来匹配字符串的开头,并确保在开头捕获的内容也匹配结尾。

^(.+)(.*)\1$

下面是测试正则表达式的链接:
https://regex101.com/r/cgowDQ/1
在Java中可以这样写:

public static void main(String[] args) {
    List<String> listTest = List.of("abXYab", "xx", "xxx", "xxxx", "javaXYZjava", "javajava", "Hello! and Hello!", "x", "", "abcd", "mymmy");
    Pattern pattern = Pattern.compile("^(.+)(.*)\\1$");
    Matcher matcher;
    for (String s : listTest) {
        matcher = pattern.matcher(s);
        if (matcher.find()) {
            System.out.printf("%s => %s%n", s, matcher.group(1));
        } else {
            System.out.printf("%s => null%n", s);
        }
    }
}

在这里你可以测试上面的代码:
https://www.jdoodle.com/iembed/v0/rEK

cngwdvgl

cngwdvgl3#

迭代到String中的最后一个元素,改变循环条件可以解决这个问题。

for (int i = 1; i < string.length(); i++)
9rbhqvlz

9rbhqvlz4#

该溶液通过所有测试:

public String sameEnds(String string) {
  String substringFront = "";
  String substringEnd = "";
  String longestSubstring = "";
  
  for (int i = 1; i < string.length(); i++) {
    substringFront = string.substring(0, i);
    substringEnd = string.substring(i);
    
    if (substringEnd.contains(substringFront)) {
      longestSubstring = substringFront;
    }
  }
  
  return longestSubstring;
}

相关问题