2017-10-16 69 views
8

該方法將採用Long並返回傳遞給該方法的任何數字的質數的LongStream用單一方法獲取功能性Java流中的主要因素?

factors.java

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()方法與謂詞來極易規避,但有一種方法可以做到同樣的事情對於素數因子但只能用單一方法?

回答

3

如果你想這樣做在一個單一的方法,無需藉助於現有的測試換貸的方法,你可以不喜歡它

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

您可以測試像

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(" * "))) 
     ); 
} 
方法
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()方法來檢查,如果你的因素是素數:

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

對於primeFactors(26).forEach(System.out::println);返回2 13

+1

您可以通過使用BigInteger.valueOf(N)避免串 –

+0

@SchiduLuca有趣的是,你最後的3個答案是關於素數:)不是'isProbablePrime',很好*可能*素數? – Eugene

+0

@Eugene上次我搞砸了「確定性」參數。如果你把''10''那麼它會給你一個''99.99''的概率) –

2

沒有記憶化,並使用LongStream您可以應用一些簡單的性能改進,比如爲生產數字流素因子流高達X/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 and Hulk - 我的立場正確,解決方案也是如此。謝謝! – diginoise