I'm making a method that takes a specified string and counts the number of times each consecutive letter appears.
For example: encode("aabbcc"); should give the output 2 2 2, since there are 2 letters appearing in sequence
My code was:
for(int i=0;i<word.length()-1;i++) {
int count=1;
if(i!=word.length()-1) {
//System.out.println(word.charAt(i));
//System.out.println(word.charAt(i+1));
try {
while(word.charAt(i)==word.charAt(i+1)) {
count++;
i++;
}
} catch (Exception e) {}
System.out.print(count+" ");
}
}
But it kept giving me an IndexOutOfBoundsException
so i just added a try and catch block but I know there is a better way
Dont look ahead like this word.charAt(i)==word.charAt(i+1)
as this gives you the error. Instead, check if letter at index i
is the same as letter from previous iteration - and if so - increment the counter.
Another approach would be to use regex.
String str = "aabbccxa";
String result = Pattern.compile("(?<=(.))(?!\\1)")
.splitAsStream(str)
.map(e -> String.valueOf(e.length()))
.collect(Collectors.joining(" "));
System.out.println(result);
How it works:
I think it's a matter of taste if this is better than the other answers. More efficient than a simple loop? I think that also depends on the input.
Welcome to SO. In general if you receive an exception you need to work out why rather than adding a catch.
A simpler solution would be:
Deque<Integer> counts = new LinkedList<>();
for (int i = 0; i < word.length(); i++) {
if (i > 0 && word.charAt(i) == word.charAt(i - 1))
counts.addLast(count.removeLast() + 1);
else
counts.addLast(1);
}
At the end of the loop, i+1
is out of bounds.
You can count them like this:
if(i > 0 && word.charAt(i) == word.charAt(i - 1))
You could test that i + 1
is less than word.length()
in your while
loop condition. You might also save word.length()
to a local variable. Like,
int len = word.length();
for (int i = 0; i < len - 1; i++) {
int count = 1;
while (i + 1 < len && word.charAt(i) == word.charAt(i + 1)) {
count++;
i++;
}
System.out.print(count + " ");
}
String str="aabbbccaaaacds";
boolean flag=false;
int cnt=1;
for (int i = 0; i < (str.length()-1); i++) { // iterate till length -1 as we are using str.charAt(i+1)
if(str.charAt(i)==str.charAt(i+1)) {
flag=true; // keep flag as true till matching chars
cnt=cnt+1;
}
else {
flag=false;
}
if(flag==false && cnt>=2) {
System.out.println("char="+str.charAt(i)+", occurance="+cnt);
cnt=1;
}
if(i==(str.length()-2) && flag) { // only used when we are at comparing last two characters
System.out.println("char="+str.charAt(i)+", occurance="+cnt);
}
}
Output:
char=a, occurance=2
char=b, occurance=3
char=c, occurance=2
char=a, occurance=4
You could collect them in a map and and print them out. This prints out the actual strings that match the count but it could easily be tailored however you want.
String str = "aabbbbcccccdddddaaaaz";
Map<Integer, List<String>> freq = Arrays.stream(
str.replaceAll("(([a-z])\\2*)", "$1,").split(",")).filter(
a -> a.length() > 1).collect(
Collectors.groupingBy(String::length));
freq.forEach((k, v) -> System.out.println(k + " : " + v));
prints the following.
2: [aa]
4: [bbbb, aaaa]
5: [ccccc, ddddd]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.