Как перевести реализацию поиска дружных номеров с императивного на функциональный? - PullRequest
1 голос
/ 05 июня 2019

У меня есть простая императивная реализация алгоритма поиска дружных чисел.Сейчас я пытаюсь сделать его более функциональным.

public static void search(){

    for(int i = 1; i < 10000; i++){
        for(int j = i+1; j < 10000; j++){
            if(isAmicable(i, j)){
                System.out.println(i + " " + j);
            }
        }
    }
}

public static boolean isAmicable(int i, int j){
    return sumProperDivisors(i) == j && sumProperDivisors(j) == i;
}

public static int sumProperDivisors(int num){
    int result = 0;
    for(int i = 1; i < num; i++){
        if(num%i == 0) result +=i;
    }
    return result;
}

Сначала я заменил циклы методом IntStreams в search ().

public static void streamed(){
    IntStream.range(1, 10000).forEach(p -> {    
        IntStream.range(p+1, 10000).forEach(o -> {
            if(isAmicable(p, o)) System.out.println(p + " " + o);
        });
    });
}

Я не вижу каких-либо состояний или побочных эффектов, которые должны быть уменьшены.Что еще нужно сделать в этой реализации, чтобы соответствовать парадигме FP?

Ответы [ 2 ]

1 голос
/ 05 июня 2019

Вот альтернатива, которая производит Map всех дружественных пар вместо побочных эффектов:

Map<Integer,Integer> pairs =
    IntStream.range(1, 10000)
             .boxed()
             .flatMap(p -> IntStream.range(p+1, 10000)
                                    .filter(o -> isAmicable(p, o))
                                    .mapToObj(o -> new SimpleEntry<>(p,o)))
             .collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue));

Конечно, с точки зрения производительности это довольно плохо, так как вы вычисляете sumProperDivisors(i) много раз для одного и того же i. Было бы более эффективно рассчитать sumProperDivisors(i) один раз для каждого i, сохранить результаты в Map и проверить, какие пары i и j удовлетворяют sumProperDivisors(i) == j && sumProperDivisors(j) == i.

1 голос
/ 05 июня 2019

Используйте фильтр вместо if(isAmicable(p, o)) и после forEach с System.out.println(p + " " + o); или карту с формированием сообщения и после System.out.println

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...