O (n) Karmaşıklığında Sıralama ile Kelime Sıklığı


12

Bir Java geliştirici pozisyonu için röportaj sırasında, bana aşağıdakiler soruldu:

İki parametre alan bir işlev yazın:

  1. bir metin belgesini temsil eden bir Dize ve
  2. döndürülecek öğe sayısını sağlayan bir tam sayı.

İşlevi, sözcük sıklığına göre sıralanmış bir Dizeler listesi döndürecek şekilde uygulayın. Çözümünüz işe yaramalıO(n) zaman nerede n belgedeki karakter sayısıdır.

Aşağıdakiler cevapladım (sözde kodda), değil O(n) daha ziyade O(nlogn)zaman nedeniyle tür. Nasıl yapılacağını anlayamıyorumO(n) saati.

wordFrequencyMap = new HashMap<String, Integer>();
words = inputString.split(' ');

for (String word : words) {
  count = wordFrequencyMap.get(word);
  count = (count == null) ? 1 : ++count;
  wordFrequencyMap.put(word, count);
}

return wordFrequencyMap.sortByValue.keys

Birisi biliyor mu veya biri bana bazı ipuçları verebilir mi?


1
Karma tablo kullanın.
Yuval Filmus

Bir hashtable kullanmak sorunu çözmez. Dahası, hashtable eski Java'dır.
user2712937

Karma tablolar genellikle karmaşıklığı azaltmanın hilesidir O(nlogn) için O(n). Eski Java olsalar bile, bu ne anlama geliyorsa. Bu özel durumu kontrol etmedim, bu yüzden haklı olabilirsin.
Yuval Filmus

@YuvalFilmus. Teşekkürler ama karma tablo zaten kullandığım karma harita ile hemen hemen aynı (2 veri yapı arasındaki büyük fark senkronizasyon, burada geçerli değildir). Benimki log (n), karma haritadaki değerleri sıralamaktan gelir.
user2712937

3
Bu arada, bu site kodlara değil, kavramlara ve algoritmalara odaklanmaktadır. Bu nedenle, normal olarak sizden Java kodunu kaldırmanızı ve yaklaşımınızın kavramsal bir tanımını vermenizi isteriz (gerekirse gerekirse kısa ve özlü sözde kodla). Ayrıca, bu sitede ilgili soru hangi veri yapılarının ve algoritmalarının kullanılacağıdır; belirli Java API'sı bu site için konu Hashtabledışıdır (ancak StackOverflow'da bu konuda soru sorabilirsiniz) ve benzer şekilde eski Java'nın olup olmadığı bu sitenin amaçları için gerçekten alakasızdır.
DW

Yanıtlar:


12

Dağıtım sayımının bir varyasyonunu öneririm:

  1. Metni okuyun ve karşılaşılan tüm kelimeleri bir üçgene yerleştirin , her bir düğümde bu düğüm tarafından temsil edilen kelimenin ne sıklıkta meydana geldiğini koruyun. Ayrıca en yüksek kelime sayımı takip edin maxWordCound. -O(n)
  2. Bir boyut dizisi başlatın maxWordCount. Giriş türü, dizelerin listeleridir. -O(n), çünkü sayı daha yüksek olamaz.
  3. Üçgeni çaprazlayın ve her düğüm için sayımla belirtilen dizi girişine karşılık gelen dizeyi ekleyin. -O(n), dizelerin toplam uzunluğu n.
  4. Diziyi azalan sırada ilerletin ve istenen sayıda dize çıktısı alın. -O(n), çünkü bu dizideki verilerin hem boyutuna hem de miktarına bağlıdır.

Üçgeni muhtemelen ilk aşamadaki diğer veri yapıları ile değiştirebilirsiniz.


+1, buna rağmen emin değilim. Döndürülecek sözcük sayısı n, karakter sayısı ile sınırlandığından O (n) 'dir, ancak sorunun sorduğu soru bu mu? Veya döndürülen kelime sayısından bağımsız bir sonuç mu?
Nikos

@NikosM. Bu ise ;nvarsayımlara değil, döndürülen kelimelerin sayısına genel bir en kötü durum üst sınırıdır.
Raphael

@ Raphael, yeap doğru Bir röportajda sorulduğu için bu konuda düşünüyorum, soruda olası hileler ..
Nikos M.

Uzay tasarruflu doğrusal zaman algoritması olup olmadığını merak ediyorum.
saadtaame

3
@saadtaame, evet, bu ilginç bir soru. Ayrı bir soru olarak ayrı ayrı göndermeye değer olabilir. Sadece alan verimliliği değil; trie çözümü, uygulamada daha yavaş hale getirebilecek (bellek hiyerarşisinin gerçek makinelerde nasıl çalıştığı göz önüne alındığında) işaretçi yoğun bir işlemdir. "Verimlilik" en kötü çalışma süresinden farklıdır. Temiz bir şey için olağandışı değilO(nlgn) işaretçi-yoğun yenmek için zaman algoritması O(n)zaman algoritması, bu soru zaten pratikte daha iyi bir seçim olabilecek bazı potansiyel algoritmaları dışlıyor gibi görünüyor.
DW

3

Algoritmanız zamanında çalışmaz O(nlogn); eklemeΘ(n) karma bir şey zaman alır Ω(n2) zaten (en kötü durum).


Aşağıdakiler yanlış ; Bunu şimdilik açıklama amaçlı olarak bırakıyorum.

Aşağıdaki algoritma en kötü durumda çalışır O(n) (bir alfabe varsayarsak) Σ sabit boyutlu), n metindeki karakter sayısı.

  1. Örneğin Ukkonen algoritmasıyla metnin bir sonek ağacını oluşturun .

    Yapı zaten bunu yapmazsa, ulaşılabilir yaprak sayısını her (iç) düğüme ekleyin.

  2. Ağacı kökten geçirin ve ilk (beyaz) boşluktaki tüm dalları kesin.

  3. Ağacı gezdirin ve her düğümdeki çocukların listesini yaprak sayılarına göre sıralayın.

  4. Ağacın verimi (soldan sağa yapraklar) artık tüm kelimelerin bir listesidir ve frekansa göre sıralanmıştır.

Çalışma zamanı ile ilgili:

  1. Ukkonen algoritması (geliştirilmiş haliyle) zamanla çalışır O(n); yaprak sayımını korumakΘ- algoritmanın maliyeti.
  2. Metinde meydana gelen her kelimenin karakteri başına bir düğümü geçmeliyiz. En fazla olduğu içinn farklı kelime karakter çiftleri, en çok ziyaret ediyoruz n düğümleri.
  3. En çok ziyaret ediyoruz n düğümler (cf 2.) ve zaman harcamak O(|Σ|log|Σ|)=O(1) düğüm başına.
  4. Verimi elde edebiliriz (ki elbette büyüklüğü O(n)) zaman içinde basit bir geçişle O(n) (çapraz başvuru 2).

Daha kesin sınırlar, çalışma zamanının farklı kelimelerin sayısı ile parametrelenmesi ile elde edilebilir; az varsa ağaç 2'den sonra küçüktür.


Algoritma yanlış (sıralamıyor). Artık doğrusal zamanın bile mümkün olduğundan emin değilim.
Raphael

3

Oluşum sayılarının toplanması O (n) 'dir, bu nedenle hile gerçekten sadece en üst k oluşum sayılarını bulur.

Yığın, en iyi k değerlerini toplamanın yaygın bir yoludur, ancak diğer yöntemler de kullanılabilir (bkz. Https://en.wikipedia.org/wiki/Partial_sorting ).

K'nin yukarıdaki ikinci parametre olduğunu ve sorun ifadesinde sabit olduğunu varsayarız (öyle görünüyor):

  1. Her düğümde oluşum sayıları olan bir kelime dizisi oluşturun.
  2. K boyutunda bir yığın başlatın.
  3. Üçgen ve min-sonda / her bir (yaprak, oluşum-sayısı) çiftini üst-k yığınına yerleştirin.
  4. Üst k yapraklarını ve sayılarını çıktılayın (bu aslında bir tür acıdır, çünkü her yaprağı bir kelimeye geri eşlemek için üst işaretçiler gerekir).

Yığın boyutu sabit olduğundan, yığın işlemleri O (1) olduğundan adım 3 O (n) olur.

Üçlü inşa edilirken, yığın dinamik olarak da muhafaza edilebilir.


1

HashMapTüm kelimeleri ve sıklıklarını toplamak için bir karma tablo (örneğin ) kullanın. Ardından, kelimeleri azalan sıklığa göre sıralamak için sayma sıralaması kullanın. Tüm frekanslar aralıktaki tamsayılar olduğundan1..n, sayma sıralaması alır O(n)saati. Toplam beklenen çalışma süresiO(n)(bu, tüm pratik amaçlar için fazlasıyla yeterlidir) (görüşmeci sorunuzun dışında kalan bir şeyden bahsetmedikçe). Bunun en kötü çalışma süresinden ziyade beklenen çalışma süresi olduğundan emin olun .

Bu, bir öğretmenin algoritma sınıfında arayacağı yanıt olmayabilir, çünkü beklendiği gibi O(n) yerine çalışma süresi O(n)en kötü çalışma süresi. Röportaj sorusunda fazladan puan almak istiyorsanız, elbette bu beklenen çalışma süresinin beklendiği gibi elden olmayan bir şekilde bahsedebilirsiniz, ancak aynı zamandaO(n) karma tablosunu daha karmaşık bir veri yapısı ile değiştirerek en kötü çalışma süresi - ve bunun gibi bir durumda algoritmalar arasında nasıl seçim yapacağınızı açıklamaktan memnuniyet duyarız.

Ya da, biraz daha güvenli oynamak istiyorsanız, cevap vermeden önce, ilk önce "beklenenler arasındaki farkı önemsiyor musunuz? O(n) çalışma süresi ve en kötü durum O(n)çalışma süresi?". buna göre Ardından terzi cevap. sormaya görüşmeci hazırlıklı olun size pratikte seçerdin nasıl. (skor Eğer öyleyse! Yani basketbol sahası dışına vurmak gerekir bir soru.)


Depolama Θ(n) karma bir şeyleri alır Ω(n2)zaten en kötü durumda zaman.
Raphael

Görüşmeciler için konuşamam, ancak özensizliklerini daha fazlası için bahane olarak kullanmakta tereddüt ediyorum. Ayrıca, bu site bilim hakkındadır (siz yukarıda yorumladığınız gibi), "nasıl daha erken ödeme alacağım" programlama hileleriyle ilgili değil.
Raphael

Bu anlayış açıkça belirtildiği sürece, bununla iyiyim. Burada karışıklıkta kurulan çok fazla soru gördüm, çünkü bazı örtük “anlayış” yanlış fikirleri teşvik etti.
Raphael

0

Hashtable tabanlı çözüm

Hashtable'ın karmaşıklığı neden yaptığından emin değilim Ω(n2) Eğer nolduğu karakter sayısı (değil kelime).

Belgedeki her karakteri yinelerseniz ve yinelediğinizde, kelimenin karma kodunu hesaplarsanız, nkarakter. Yani, bir harfle karşılaşır karşılaşmaz kelime başlar, bu yüzden kelime bitene kadar hash hesaplamaya başlayın (noktalama için bazı özel durumlar vardır, ancak bunlar karmaşıklığı etkilemez). Her kelime için, karma hesaplandıktan sonra, onu bir hashtable'a ekleyin. Bu, her kelimeyi iki kez gözden geçirmekten kaçınmaktır, yani ilk önce kelimeleri bulmak için belgeyi tekrarlamak ve daha sonra bunları bir karma tabloya eklemek, ancak bu durumda karmaşıklık da olabilirΩ(n).

Hashtable'daki çarpışmalar kesinlikle bir sorundur ve orijinal hashtable'ın ne kadar büyük olduğuna ve hash algoritmasının ne kadar iyi olduğuna bağlı olarak, O(1) ekleme ve sayma işlemleri için ve böylece O(n)algoritma için, ancak bellek pahasına. Ancak, en kötü durumun nasıl ortaya çıkabileceğini hala takdir edemiyorumO(n2) Eğer n karakter sayısıdır.

Varsayım, karma algoritmanın karakter sayısına göre zaman içinde doğrusal olmasıdır.

Radix sıralama tabanlı çözüm

Alternatif olarak, İngilizce varsayarsak, kelimelerin uzunluğu iyi bilindiği için, bunun yerine bir ızgara oluşturur ve O(kN) nerede k İngilizcedeki bir kelimenin maksimum uzunluğu ve Ntoplam kelime sayısıdır. verilmişn belgedeki karakter sayısıdır ve k bir sabittir, asimptotik olarak bu miktarlar O(n).

Şimdi her kelimenin sıklığını sayın. Kelimeler sıralandığından, aynı veya farklı olup olmadığını görmek için her kelimeyi bir önceki kelimeyle karşılaştıracağız. Aynı ise, kelimeyi kaldırır ve öncekine bir sayı ekleriz. Farklıysa, sadece 1 sayısını yapın ve devam edin. Bu gerektirir2n karşılaştırmalar nerede n karakter sayısı ve dolayısıyla O(n) bir bütün olarak karmaşıklık içinde.

İngilizce'deki en uzun birkaç kelime gülünç derecede uzundur , ancak daha sonra kelime uzunluğu makul bir sayı (30 veya daha küçük gibi) ile sınırlanabilir ve beraberinde gelebilecek hata payını kabul eden sözcükleri kısaltabilir.


(1) Çoğu metinde kelimelerin maksimum uzunluğu bir sabitle sınırlandığından, kelimelerin sayısı Θ(n)de. (2) Karma fonksiyonuna bağlı olarak, kelimeyi okurken karmayı anında hesaplamak mümkün olmayabilir. (3) En kötü durumda, tüm kelimeler tablodaki aynı konuma hash ekler ve arama yaparΘ(n).
FrankW

Merhaba FrankW. (2) Anında hesaplayabileceğimiz işlevi (yani bir haddeleme karması) seçebileceğimizi belirtiyorum. Olmasa bile, karma işlem doğrusal zaman olduğu sürece genel karmaşıklık değişmez, çünkü okuma ve karma yapmaO(n+n)operasyonlar. (3) Tabii ki, ama yine algoritma seçimine bağlı. Kelimeler farklıysa çok daha iyi olan birçok algoritma vardır. Aynı sözcük için, tek bir girişteki sayımı artırırsınız. Bir benzetme olarak, bir sıralama algoritması seçmem gerektiğinde, en kötü durumO(n2)ama genellikle daha iyi seçerim :-)
Omer Iqbal

(3) Hangi hash fonksiyonunu seçerseniz seçin, o fonksiyonun bozulduğu bir giriş bulabilirim. Ve girdiyi bildikten sonra hash işlevini seçmek genellikle bir seçenek değildir. (Ve muhtemelen
değindiğiniz yorumun

Karma tablo neden O(n2)en kötü durum karmaşıklığı? Çünkü prensipte bir hashtable'ın en kötü çalışma süresi çok kötüdür. Pratikte bu en kötü durum neredeyse hiç ortaya çıkmaz (özellikle hash fonksiyonunu rasgele ve diğer tekniklerle doğru seçerseniz) ve bunun nedenini haklı çıkarmak için teoremleri bile kanıtlayabilir, ancak bu asimptotik karmaşıklık hakkında bir soru ise , bunun gibi pratik hususlar tartışmalı olarak pencereden dışarı çıkar (veya en azından duyabileceğiniz argüman budur).
DW

Sıradan karma tablo ekler O(n2)çünkü bir çarpışma, öğenin başka bir yere yerleştirilmesini gerektirir. Burada kopyaları eklememiz gerekmiyor. 1) Aynı kelime tekrarlar: sonra sayı, bu olması garanti edilirO(1)artı karma süresi. 2) Farklı kelimeler aynı karma: bu, karma ne kadar iyi / kötü olduğu ve tablonun boyutu çok küçükse soru. KatılıyorumΩ(1), ancak seçimlere bağlı olarak, "birinin yaklaşabileceğini yakınO(1) "" tablo boyutu ve işlev (ler) in bizi yakınlaştırabileceğini tartışabiliriz. O(1).
Ömer İkbal
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.