bugfix> java > 投稿

Javaを習得するために、私は プロジェクトオイラーの問題23  ここで、すべての正の整数の合計を見つける必要があります 2つの豊富な数字の合計として書かれています。私のソリューションはJava 8ストリームを使用しています。私 ここに実際の答えを投稿することでそれを台無しにしませんが、私は私の議論します ソリューションに到達するための戦略。

最初に、IntStreamを使用して豊富な数字のリストを作成します。

List<Integer> abundants = IntStream.range(1, EULER23_MAX)
        .filter(i -> Util.sumOfDivisors(i) > i)
        .boxed()
        .collect(Collectors.toList());

次に、リストに基づいて、2つの豊富な数値の合計のセットを作成します 最大より:

private Set<Integer> calcSumsOfTwoAbundants(List<Integer> abundants) {
    Set<Integer> iset = new HashSet<>();
    Integer[] arr = abundants.toArray(new Integer[abundants.size()]);
    for (int i = 0; i < arr.length - 2; i++) {
        for (int j = i; j < arr.length - 1; j++) {
            int sum = arr[i] + arr[j];
            if (sum <= EULER23_MAX) {
                iset.add(sum);
            }
        }
    }
    return iset;
}

最後に、以下のすべての数値を除外する別のストリームを生成します 2つの豊富な合計のセットに存在する最大値、そして私はそれを得るためにそれを合計します 結果に。

result = IntStream.range(1, EULER23_MAX)
        .filter(x -> !sumsOfTwoAbundants.contains(x))
        .sum();

私の質問はこれです:  calcSumsOfTwoAbundants でロジックをエンコードするにはどうすればよいですかに ネストされた for の代わりに、流fluentな構文を使用するループ?私は試しました いくつかの異なる点がありますが、私は「ストリームはすでに エラーメッセージまたは完全に間違った結果が表示されます。また、 ネストされた for ループはおそらくストリームを使用するよりも高速ですが、これは 純粋に知的運動...これは私が今持っているものです:

// wrong results
private Set<Integer> calcSumsOfTwoAbundantsAlt(List<Integer> abundants) {
    return abundants.stream()
            .filter(i -> abundants.stream()
                    .anyMatch(j -> (i + j) <= EULER23_MAX))
            .collect(Collectors.toSet());
}

回答 1 件
  • 最も直接的な同等物は、各forループを IntStream.range に置き換えることです。   flatMap でそれらをネストする :

    Set<Integer> iset = IntStream.range(0, arr.length - 2)
            .flatMap(i -> IntStream.range(i, arr.length - 1)
                    .map(j -> arr[i] + arr[j]).filter(s -> s <= EULER23_MAX))
            .boxed().collect(Collectors.toSet());
    
    

あなたの答え