2016-06-14 18 views
5

Ben 2..Nhesaplama asal sayılar (dere ve lambda'lar)

private static LongStream getPrimesStream(long number) { 
    return LongStream.range(2, number + 1) 
      .filter(PrimeStreamTest::isPrime); 
} 

private static boolean isPrime(final long number) { 
    return number == 2 || (number % 2 != 0 && LongStream 
      .range(2, (long) Math.ceil(Math.sqrt(number + 1))) 
      .filter(n -> n % 2 != 0) 
      .noneMatch(divisor -> number % divisor == 0) 
    ); 
} 

Ben 2..sqrt aralığında kontrol ederek bunu optimize tüm asal sayılarını almak için aşağıdaki kodu yazdım (n) ve çift sayıları filtrelemek, ama şimdi daha önceden bulunan tüm primleri (bellek umurumda değil) saklayarak onu daha da optimize etmek istiyorum, böylece bu primerler tarafından bölünebilen sayıları filtreleyebilirim, ve sadece bölünebilenleri değil 2 Daha iyi çözümler olduğunu biliyorum, ama sadece lambda ve akışlar üzerinde bir alıştırma.

+0

daha iyi optimizasyon anyMatch (hiç noneMatch() (a) değişikliğe olduğuna inanıyoruz denemek ve (b) sahip filtre işlemi gerçekten çok olmadığını kontrol sınırlıdır sonucu etkisiz hale 2..sqrt (giriş) aralığındaki sayı 2'ye bölünür ve 3,5 gibi diğer asal sayıları kontrol etmez. Tüm bu adımlar yerine akış, sayıyı bölündüğü anda geri döndürür. 2,3,4,5, .... – Baski

+2

@Baski: Neden noneMatch() 'den' anyMatch() 'ye geçmeyi ve sonucun olumsuzluğu değiştirdiğini düşünüyorsunuz? – Holger

+2

Hız için bellek maliyetini optimize etmek istiyorsanız, Eratosthenes'in elekini bir "BitSet" kullanarak uygulayın. Ancak, bu akışlarda bir alıştırma olduğu için, karşı test etmek için ana faktörleri almak için 'isPrime' içinde' getPrimesStream' kullanabilirsiniz: 'return number == 2 || getPrimesStream ((uzun) ceil (sqrt (sayı)). noneMatch (divisor -> number% divisor == 0); – Misha

cevap

3

ama şimdi daha daha önce depolayarak optimize etmek istiyorum akış boru hattı, yani ortasında bu değerleri depolamak gerektirecektir yana bir ara işlem ve en çok ara madde akışı için asal

bulundu İşlemler, iş için yanlış aracı kullanmaya çalıştığınız belgelerine göre vatansız olmalıdır.

Durum bilgisi, bir akışın Spliterator kopyasını alıp, özel bir sargıya sarmak ve yeni bir akışa yeniden sarmak suretiyle gerçekleştirilebilir, ancak bu durumda bunun esas olarak akış yöneltme kanalınızın yaptığı şeyden kaynaklandığını düşünürsek bu oldukça uygun görünmektedir.

bunun yerine fork-join framework veya CompletableFuture içine bakmak isteyebilirsiniz bir durum bilgisi ve paralelleştirilebilir hesaplama görevi çalıştırmak için çalışıyoruz beri. Birincisi, paralel akış uygulamasının bir parçası olarak kullanılır ve ikincisi, hesaplamaları ve sonuçlarını oluşturmayı kolaylaştırır.

1

) bu

public static boolean isPrime(final long number) { 
    return LongStream.range(2,(long) Math.ceil(Math.sqrt(number + 1))).noneMatch(x -> number % x == 0); 
} 
+0

Neden + 1 sayısını biliyorum? –

+0

@JigarNaik Yanlış olabilirim. Sadece yuvarlama hatalarından kaçınmak için yaptım. – dehasi

+0

Neden anyMatch() ve negation sign yerine noneMatch() öğesini çağırmıyorsunuz? –