CodePudding user response:
There are a couple of problems within your code:
You stop iterating before reaching the last character, instead of iterating till length/2 included (you need to check the beginning and end without overlapping so no need to iterate till the end or almost).
You
substringEnd
should start from the right side, so it should look likestring.substring(string.length() - i);
.
Here is a fixed implementation:
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);
}
}
}
Here is a link to test the code above:
https://www.jdoodle.com/iembed/v0/rEO
However, to make it more concise you could use a regex which uses a capturing group with a greedy quantifier to match at the beginning of the string and make sure that what has been captured at the beginning matches also at the end.
^(. )(.*)\1$
Here is a link to test the regex:
https://regex101.com/r/cgowDQ/1
This could be written in Java like so:
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);
}
}
}
Here you can test the code above:
https://www.jdoodle.com/iembed/v0/rEK
CodePudding user response:
In addition to the technical issues that @Dan and others have aptly pointed out, I want to highlight the issue of unnecessary complexity, which in many cases leads to such logical errors.
Given this, and considering that this is a challenge, I would prefer a minimalist approach, like the one below, which is self-explanatory and hence simple to comprehend and debug.
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 "";
}
CodePudding user response:
Iterate till the last element in the String, changing the loop condition fixes the problem.
for (int i = 1; i < string.length(); i )