2017-10-16 14 views
8

Phương pháp này sẽ lấy số Long và trả về số LongStream của số nguyên tố cho bất kỳ số nào được chuyển cho phương thức.Lấy các yếu tố chính trong các luồng Java chức năng bằng một phương thức đơn lẻ?

factors.java

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

Bằng cách sử dụng các phương pháp trên để tìm các yếu tố phổ biến thứ nhất là 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; 
} 

Tôi hiểu điều này nên được dễ dàng phá vỡ với việc sử dụng một cách đơn giản isPrime() phương pháp với một vị ngữ, nhưng là có một cách để làm điều tương tự cho cho các yếu tố chính nhưng chỉ với một phương pháp duy nhất?

Trả lời

3

Nếu bạn muốn làm điều đó trong một phương pháp duy nhất mà không sự trợ giúp của một hiện kiểm tra-cho-thủ phương pháp, bạn có thể làm điều đó như

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

Bạn có thể kiểm tra các phương pháp như

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 

không cần phải nói, đây không phải là cách tiếp cận hiệu quả nhất ...

2

Bạn có thể tận dụng isProbablePrime() phương pháp 's BigInteger để kiểm tra xem các yếu tố của bạn là số nguyên tố:

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

Đối primeFactors(26).forEach(System.out::println); nó trả 2 13.

+1

Bạn có thể tránh được bằng cách sử dụng chuỗi BigInteger.valueOf (n) –

+0

@SchiduLuca thú vị, 3 câu trả lời cuối cùng của bạn là về số nguyên tố :) không phải là 'isProbablePrime', cũng là một * có thể xảy ra * nguyên tố? – Eugene

+0

@Eugene thời gian qua tôi đã sai lầm với tham số '' certainty''. Nếu bạn đặt '' 10'' thì nó sẽ cho bạn một xác suất '99,99'') –

2

Without memoization, và sử dụng LongStream bạn có thể áp dụng vài cải tiến hiệu suất đơn giản như cho dòng thừa số nguyên tố sản xuất một dòng số lên đến 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); 
} 

nào cho rất lớn x sẽ là vấn đề. Tuy nhiên, giải pháp này lặp lại thử nghiệm của x % n == 0 cho mỗi n trong mỗi 2 dòng, yêu cầu ghi nhớ.

+0

Làm thế nào để đáp ứng yêu cầu sử dụng 1 phương pháp? – user1803551

+2

Trên cơ sở nào bạn cho rằng các yếu tố chính không thể lớn hơn căn bậc hai của chúng? – Holger

+0

@Holger và Hulk - Tôi đã sửa chữa và giải pháp cũng vậy. Cảm ơn bạn! – diginoise

Các vấn đề liên quan