2017-10-16 3 views
8

このメソッドは、Longを受け取り、メソッドに渡される桁の素数のLongStreamを返します。共通因子を見つけるために、上記の方法を利用factors.java機能的なJavaストリームの素因数を1つの方法で得るには?

public LongStream factors(long x){ 
    LongStream factorStream = LongStream.range(1, x+1).filter(n -> x%n == 0); 
    return factorStream; 
} 

最初OKあります。

primeFactors.java

public LongStream primeFactors(long x){ 
    LongStream primeFactorStream = factors(x).filter(n -> factors(n).count() == 0); 
    //doesn't work as factors.java returns a LongStream, which might include non-prime factors, which will not equate to zero. 
    return primeFactorStream; 
} 

私は、これは簡単なisPrime()述語と法を用いて回避する必要があります理解しますが、同じことを行う方法がありますの素因数はですが、1つの方法でのみですか?

答えて

3

既存のテストのためのプライム法の助けを借りずに、単一の方法でそれをしたい場合は、あなたが

IntStream.concat(IntStream.rangeClosed(2, 15), IntStream.rangeClosed(90, 110)) 
     .forEach(number -> System.out.printf("%3d = %s%n", number, 
      primeFactors(number) 
       .mapToObj(d -> { 
        int p = 0; 
        for(long l = number; l%d == 0; l /= d, p++) l++; 
        return p == 1? String.valueOf(d): d + "^" + p; 
       }) 
       .collect(Collectors.joining(" * "))) 
     ); 
} 
のようなメソッドをテストすることができます

public static LongStream primeFactors(long x) { 
    return LongStream.rangeClosed(2, x) 
        .filter(n -> x % n == 0) 
        .filter(n -> LongStream.rangeClosed(2, n/2).noneMatch(i -> n%i==0)); 
} 

ようにそれを行うことができます

2 = 2 
    3 = 3 
    4 = 2^2 
    5 = 5 
    6 = 2 * 3 
    7 = 7 
    8 = 2^3 
    9 = 3^2 
10 = 2 * 5 
11 = 11 
12 = 2^2 * 3 
13 = 13 
14 = 2 * 7 
15 = 3 * 5 
90 = 2 * 3^2 * 5 
91 = 7 * 13 
92 = 2^2 * 23 
93 = 3 * 31 
94 = 2 * 47 
95 = 5 * 19 
96 = 2^5 * 3 
97 = 97 
98 = 2 * 7^2 
99 = 3^2 * 11 
100 = 2^2 * 5^2 
101 = 101 
102 = 2 * 3 * 17 
103 = 103 
104 = 2^3 * 13 
105 = 3 * 5 * 7 
106 = 2 * 53 
107 = 107 
108 = 2^2 * 3^3 
109 = 109 
110 = 2 * 5 * 11 

言うまでもなく、これは最も効率的な方法ではありません...

2

あなたの要因が素数かどうかを確認するためにBigIntegerisProbablePrime()方法を利用することができますprimeFactors(26).forEach(System.out::println);については

public static LongStream primeFactors(long x){ 
    LongStream primeFactorStream = factors(x) 
      .filter(n -> new BigInteger(String.valueOf(n)).isProbablePrime(10)); 
    return primeFactorStream; 
} 

それは2 13を返します。 メモ化、そしてあなたがX/2までの数字の流れを生成する素因数のストリームのようないくつかの単純なパフォーマンスの向上を適用することができLongStreamを使用せずに

+1

あなたはBigInteger.valueOf(n)を使用して文字列を避けることができ –

+0

@SchiduLucaおもしろい、あなたの最後の3つの答えは素数についてです:) isProbablePrimeではなく、おそらく素数ですか? – Eugene

+0

@Eugene前回私は '' certainty''パラメータを使いこなしました。 '' 10''を置くと '' 99.99''の確率が与えられます) –

2

public static LongStream factors(long x){ 
    return LongStream.rangeClosed(2, x/2).filter(n -> x % n == 0); 
} 

public static LongStream primeFactors(long x){ 
    return LongStream.rangeClosed(2, x/2) 
    .filter(n -> x % n == 0).filter(n -> factors(n).count() == 0); 
} 

これは非常に大きな用xが重要です。 しかし、この解決策は、2つのストリームのそれぞれのnごとにx % n == 0のテストを繰り返し、メモを求めます。

+0

これは1つの方法の使用要件をどのように満たしていますか? – user1803551

+2

どのような場合、素因数は平方根よりも大きくできないと仮定していますか? – Holger

+0

@HolgerとHulk - 私は訂正され、解決策もあります。ありがとうございました! – diginoise

関連する問題