Çok büyük bir dosyada en çok oluşan öğeyi bulma


12

Bu röportaj sorusunun çok sorduğunu duydum ve iyi cevapların ne olabileceği hakkında bazı fikirler almayı umuyordum: 10+ GB büyük bir dosyanız var ve en çok hangi öğenin en iyi şekilde oluştuğunu öğrenmek istiyorsunuz, iyi bir yol nedir Bunu yapmak için?

Çok fazla bellek kullandığınız için haritayı yinelemek ve izlemek muhtemelen iyi bir fikir değildir ve parçayı girdiler olarak tutmak en iyi seçenek değildir, çünkü bu soru sorulduğunda genellikle dosya zaten vardır.

Diğer düşünceler yinelenecek ve birden çok iş parçacığı tarafından işlenecek dosyayı bölme dahil ve daha sonra bu sonuçları birleştirmek, ama haritalar için bellek sorunu hala orada.


2
Dosyanın unsurları nelerdir? Bunlar ip mi? Öğeler için karakter alırsanız, haritanın bir bellek sorunu olmaz. Elemanlar kelimeler ise, o zaman yine de sorun olmayacağını düşünüyorum. Tüm olası alt dizeleriniz varsa, sorun yaşayabilirsiniz ...
Nejc

1
Koşul "toplam öğelerin yarısından fazlasını gösteren bir öğe" ise, doğrusal bir çözüm vardı.
st0le

Elemanların genellikle ipler olduğuna inanıyorum. Ancak haritanın nasıl bir sorun olmadığını görmüyorum. Her öğenin benzersiz olduğu en kötü durumda, bellek gereksiniminizi iki katına çıkarmadınız mı?
Pat

1
Boyer-Moore çoğunluk aday algoritması uygulanabilirse, doğrusal zamanda çalışır ve yerinde olur.
Juho

Yanıtlar:


6

>1/kO(k)O(). Sorun artık ağır vurucular sorunu olarak biliniyor (sıkça görülen elemanlar ağır vuruculardır).

>1/kk

k=2

  • dosyanın geçerli öğesi depolanan öğeyle aynıysa, sayımı bir artırın
  • dosyanın geçerli öğesi depolanan öğeden farklıysa sayımı bir azaltın
  • güncellenen sayım 0 ise, saklanan elemanı "dışarı atın" ve dosyanın geçerli elemanını saklayın; sayımı 1'e çıkar
  • dosyanın bir sonraki öğesine ilerle

Bu prosedür hakkında biraz düşünmek, bir "çoğunluk" öğesi, yani zamanın yarısından fazlasında meydana gelen bir öğe varsa, o öğenin tüm dosya işlendikten sonra depolanan öğe olacağına ikna edecektir.

kk1k1kk

k11/kO(k)

k1/kk1


Boyer-Moore veya Misra-Gries-Demaine algoritmalarını kullanamazsınız. Belirtildiği gibi sorun farklıdır: Çoğunluk öğesi değil, oluşumları tüm öğelerin oluşumları> = olan bir öğe için arama yaparsınız. İşte basit bir karşı örnek. N toplam eleman sayısı olsun , n = 2k + 1 olsun . İlk k öğelerinin 0, sonraki k öğelerinin 1 ve son öğenin 2 olmasına izin verin. Boyer-Moore algoritması son öğeyi (2) potansiyel çoğunluk adayı olarak rapor edecektir. Ancak, bu özel örnek için, çıktı 0 veya 1 olmalıdır.
Massimo Cafaro

O(1)Ω(n)

Az önce yanlış bir varsayım yaparsanız yanlış sonuçlar elde edebileceğinizi belirtmiştim. Daha iyi olan, küçük bir bellek alanı ve potansiyel olarak yanlış bir sonuç veya daha fazla belleğe mal olmasına rağmen doğru sonuç? Potansiyel olarak yanlış bir sonuç seçmek zorunda kalsaydım, aslında doğru olmadığını bilmediğim bir şey varsayarak Boyer-Moore yerine rastgele bir algoritma için giderdim.
Massimo Cafaro

@MassimoCafaro, almanız gereken bir ödünleşim değildir. i dosya üzerinde tek bir geçiş işaret varsayalım tatmin olup olmadığını kolayca doğrular!
Sasho Nikolov

@MassimoCafaro ve bu sadece önemsiz bir çözüm! ek bir geçiş olmadan bir CM çizimi ile varsayım yüksek olasılıkla doğrulanabilir.
Sasho Nikolov

3

Açık cevap elbette bir karma harita tutmak ve Nejc zaten önerildiği gibi dosya içinde hareket ederken öğelerin oluşumunun bir sayaç depolamaktır. Bu (zaman karmaşıklığı açısından) en uygun çözümdür.

Θ(nlogn).


Huffman kodlama yaklaşımı hakkında daha fazla bilgi verebilir misiniz? Daha önce bir Huffman kodlayıcı yazdım ama bir süredir bu durumda tam olarak nasıl kullanardınız?
Pat

@Pat Nevermind bu kısmı sabah çok erken oldu ve bir şekilde girdiyi sıkıştırmanın mantıklı olacağını düşündüm.
Jernej

1

En yaygın öğe, bir sonraki ortak öğeden önemli bir farkla daha yaygınsa ve farklı öğelerin sayısı dosya boyutuna göre azsa, rastgele birkaç öğeyi örnekleyebilir ve örneğinizdeki en yaygın öğeyi döndürebilirsiniz.


Dahası, birçok kez meydana gelen az sayıda eleman varsa, bunları örnekleyerek bulabilir ve daha sonra sadece bu elemanları tam olarak sayabilirsiniz.
Maksimum
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.