Номер вхождения IntStream Java - PullRequest
0 голосов
/ 10 октября 2018

Я хочу определить метод с именем countRepeats, который принимает список цифр от 0 до 9 и возвращает количество вхождений соседних повторяющихся букв.

Например,

Контрольный пример 1: массив {0, 1, 2, 2, 1, 2, 2, 1, 3, 3, 1} содержит три повторяющихся цифры

Контрольный пример 2: массив {0, 1, 1, 1, 1, 2} имеет одно вхождение

Ниже приведены мои коды:

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();
}

Однако мне не удалось получить желаемыйрезультат для моего теста 2. Кто-нибудь может просветить меня?

Ответы [ 2 ]

0 голосов
/ 10 октября 2018

Основываясь на оригинальном решении автора, если мы проверим, является ли повторяющаяся пара частью большей последовательности (и проверим конец массива), мы сможем избежать бокса.

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();
    }
}

Это не совсем таксильная точка потоков.

(строка

                   i+2 >= array.length ||

действительно должна быть

                   i >= array.length-2 ||

, чтобы избежать целочисленного переполнения, вызывающего ArrayOutOfBoundsException. Старые языки и ихнеработающие целые числа ...)

0 голосов
/ 10 октября 2018

При этом используются предикаты, сравнивающие последовательные элементы:

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();
}

Первая операция filter предназначена для устранения дубликатов с целью принудительного подсчета 1, когда элемент повторяется более 2 раз подряд.Второй просто удаляет элементы, которые не повторяются последовательно.

...