我有一个简单的命令式实现,用于搜索友好数字的算法。现在我尝试让它更实用。
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;
}
首先,我在 search() 方法中用 IntStreams 替换了循环。
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 范式?
最佳答案
这里有一个替代方案,可以生成所有友好对的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));
当然,就性能而言,这非常糟糕,因为您对同一个 i
计算 sumProperDivisors(i)
多次。为每个 i
计算一次 sumProperDivisors(i)
一次,将结果存储在 Map
中,并检查哪些对 code>i
和 j
满足 sumProperDivisors(i) == j && sumProperDivisors(j) == i
。
关于java - 如何将友好号码搜索的实现从命令式转变为功能性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56457882/