I need to create a program in Java that finds all the occurrences of a 4-letter string, in this case "lane"
, within the given String.
Comparison should be case-insensitive, and the second letter of the matching substring should not be taken into account while evaluating whether a substring matches or not.
My current code can handle some cases, but in others it returns an incorrect number of occurrences or produces an IndexOutOfBoundsException
.
I tried the following cases:
"Lanee"
- returns1
, as expected ("Lane"
matches"lane"
)."LineLone"
- returns2
, as expected (both"Line"
and "Lone"match
"lane"`)."LLoenLL"
- produces anIndexOutOfBoundsException
."enaLLLmnee"
- returns0
, but should be1
"LLONElllneL"
- produces anIndexOutOfBoundsException
.
My code:
public class Stringer {
public Stringer() {}
public int getOccurrences(String s) {
String lower = s.toLowerCase();
int occurrences = 0;
int x = 0;
while (x < lower.length()) {
int traverser = lower.indexOf("l", x);
if (traverser != -1 && lower.length() > 3) {
String sub = lower.substring(x = 2, x = 2);
if (sub.equals("ne")) {
occurrences ;
}
} else {
break;
}
}
return occurrences;
}
}
How can I resolve this issue?
CodePudding user response:
Basically, you need to iterate over the given string, checking if the current character is equal to 'l'
(the first character of "lane"
).
And if the that's the case, you need to check the if character at the current index 2
and 3
match 'n'
and 'e'
respectively. If all these characters match, the number of occurrences should be incremented and the index advanced by 3
to avoid double-checking the same positions.
Note that termination condition in the loop is i < lower.length() - 3
because the length of the target string "lane"
is 4
and while checking the first character of a substring at index i
we need to be able to the last substring character at index i 3
.
public static int getOccurrences(String s) {
String lower = s.toLowerCase();
int occurrences = 0;
for (int i = 0; i < lower.length() - 3; i ) {
if (lower.charAt(i) == 'l' &&
lower.charAt(i 2) == 'n' &&
lower.charAt(i 3) == 'e') {
occurrences ; // incrementing the number of occurrences
i = 3; // advancing the index
}
}
return occurrences;
}
main()
public static void main(String[] args) {
System.out.println(getOccurrences("Lanee"));
System.out.println(getOccurrences("LineLone"));
System.out.println(getOccurrences("LLoenLL"));
System.out.println(getOccurrences("enaLLLmnee"));
System.out.println(getOccurrences("LLONElllneL"));
}
Output:
1
2
0
1
2
CodePudding user response:
You can also make use of regular expressions to solve this.
public static void main(String[] args) {
System.out.println(getOccurrences("Lanee"));
System.out.println(getOccurrences("LineLone"));
System.out.println(getOccurrences("LLoenLL"));
System.out.println(getOccurrences("enaLLLmnee"));
System.out.println(getOccurrences("LLONElllneL"));
}
prints
1
2
0
1
2
Regular expressions can be used to match patterns in strings
(?i)
- uses thei
flag which says ignore case when matchingl.ne
- is the string to match. The.
stands for any character- the Matcher takes the source string and iterates across the string trying to find matches. If it returns true, count is updated.
public static int getOccurrences(String s) {
Matcher m = Pattern.compile("(?i)l.ne").matcher(s);
int count = 0;
while (m.find()) {
count ;
}
return count;
}
You could also use the following method signature to take any target string. Then you just need to build the expression using the target.
public static int getOccurrences(String s, String target) {
String expression = "(?i)" target.substring(0,1) "." target.substring(2);
Matcher m = Pattern.compile(expression).matcher(s);
int count = 0;
while (m.find()) {
count ;
}
return count;
}
Calling it like this, the output would be the same.
System.out.println(getOccurrences("Lanee", "lane"));
System.out.println(getOccurrences("LineLone", "LANE"));
System.out.println(getOccurrences("LLoenLL", "LaNe"));
System.out.println(getOccurrences("enaLLLmnee","lanE"));
System.out.println(getOccurrences("LLONElllneL", "Lane"));