Reputation:
I want to define a method named countRepeats that takes in a List of digits 0 to 9 and returns the number of occurrences of adjacent repeated letters.
For example,
Test case 1: the array {0, 1, 2, 2, 1, 2, 2, 1, 3, 3, 1} has three occurrences of repeated digits
Test case 2: the array {0, 1, 1, 1, 1, 2} has one occurrence
Below are my codes:
List<Integer> intlist = new ArrayList<Integer>();
int [] array = new int[]{};
while(sc.hasNext()){
intlist.add(sc.nextInt());
array = intlist.stream().mapToInt(i->i).toArray();
}
System.out.println("Number of occurrences: " + countRepeats(array));
public static long countRepeats(int [] array){
return IntStream.range(0, array.length-1)
.filter(n -> array[n] > 0)
.filter(i -> (array[i] == array[i+1]))
.peek(System.out::println)
.count();
}
However, I failed to get the desired outcome for my test case 2. Anyone can enlighten me ?
Upvotes: 7
Views: 2971
Reputation: 147154
Building on the original poster's solution, if we check whether a repeated pair is part of a larger sequence (and check end of array) then we can avoid boxing.
import java.util.*;
import java.util.stream.*;
interface CountRepeats {
static void main(String[] args) {
test(0, 1, 2, 2, 1, 2, 2, 1, 3, 3, 1);
test(0, 1, 1, 1, 1, 2);
}
static void test(int... digits) {
System.err.println(
countRepeats(digits)+": "+Arrays.toString(digits)
);
}
static long countRepeats(int[] array) {
return IntStream.range(0, array.length-1)
.filter(i ->
array[i] == array[i+1] && (
i+2 >= array.length ||
array[i] != array[i+2]
)
)
.count();
}
}
This isn't really streams' strong point.
(The line
i+2 >= array.length ||
really should be
i >= array.length-2 ||
to avoid an integer overflow causing an ArrayOutOfBoundsException
. Old languages and their broken integers...)
Upvotes: 3
Reputation: 45309
This uses predicates that compare consecutive elements:
public static long countRepeats(int [] array){
return IntStream.range(1, array.length)
.filter(i -> i - 2 < 0 || array[i - 2] != array[i])
.filter(i -> array[i] == array[i - 1])
.count();
}
The first filter
operation is intended to eliminate duplicates to force a count of 1 where an element is repeated more than 2 times in a row. The second one simply removes elements that aren't repeated consecutively.
Upvotes: 1