Diziyi itfa edilmiş sabit sürede başlat - bu numaraya ne denir?


13

Dizi erişiminin performansını, temizleme sırasında üzerinde yineleme yapma ihtiyacına karşı işleyen bu veri yapısı vardır. Her girişte bir nesil sayacı ve ayrıca bir küresel nesil sayacı tutarsınız. "Temizle" işlemi üretim sayacını artırır. Her erişimde, yerel ve global nesil sayaçları karşılaştırırsınız; farklıysa, değer "temiz" olarak kabul edilir.

Bu son zamanlarda Stack Overflow'daki bu cevapta ortaya çıktı , ancak bu hilenin resmi bir adı olup olmadığını hatırlamıyorum. Yapar?

Bir kullanım örneği Dijkstra'nın sadece küçük bir düğüm alt kümesinin gevşetilmesi gerekiyorsa ve bunun tekrar tekrar yapılması gerekiyorsa algoritmasıdır .


2
İlginç bir numara, ama oldukça genel bir yükü var. Yani hangi kullanımları fiyat ödediği ortak bir işlem olarak dizi temizleme var merak ediyorum? (Samimi soru!)
Joachim Sauer

@JoachimSauer: Düzenlendi.
krlmlr

Hem bellek kullanımı hem de maliyet için genel durumda çok pahalı görünüyor. Bu teknik için kullanım durumu çok spesifik olmalıdır.
Martin York

3
@ Joachim: Arabellekleri kabaca oluşturmak için hızlı bir şekilde temizlemek için kullanılır. Onlar sadece 64kb başına "net bir bit" veya böyle bir şey var.
DeadMG

3
@ user946850 Eğer pahalı bir operasyon daha örn O (1) daha katkıda bulunmadığını genel resim içinde nadiren yeterli olur kanıtlamak anlamına "amorti"

Yanıtlar:


2

Yukarıda adı geçen yaklaşım, her hücrenin, dizinin kaç kez yeniden başlatılması gerektiğini tutacak kadar büyük bir sayı tutabilmesini gerektirir; bu, önemli bir alan cezasıdır. Bir yuva hiçbir zaman meşru olarak yazılmayacak en az bir değer tutabilirse, bir O(Wlg(N))zaman cezası eklemek pahasına başka (sabit olmayan) bir boşluk cezası kullanmaktan kaçınılabilir , burada arasındaki farklı dizi yuvalarının Wsayısı temizleme işlemleri ve dizi boyutudur. Örneğin, birinin -2,147,483,647 ile 2,147,483,647 arasındaki tam sayıları depolayacağını (ancak asla -2,147,483,648) tamsayı depolayacağını ve boş dizi öğelerinin sıfır olarak okunmasını istediğinizi varsayalım. Diziyi -2.147.483.648 ile doldurarak başlayın (bu değeri arayınNB). Uygulama için bir dizi yuvası okurken, değeri Bsıfır olarak bildirin. Dizi yuvası yazmadan önce I, bu tutulan kontrol Bve bu durumda ve Ibirden büyük, yuvaya bir sıfır depolamak olan I/4(bu tutulursa, ve bu konum için de benzer bir kontrol yaptıktan sonra B, I/16vs.).

Diziyi temizlemek için I, dizi tabanına bağlı olarak 0 veya 1'e eşit olarak başlayın (açıklanan algoritma her ikisi için de çalışır). Daha sonra aşağıdaki prosedürü tekrarlayın: Öğe Iise B, artırılırsa Ive eğer bunu dörtten bir kat verirse, dörde bölün (bölme 1 değerini verirse sonlandırın); öğe Iyoksa B, Borada saklayın ve Idört ile çarpın ( Isıfırdan başlarsa, dört ile çarpmak sıfır bırakır, ancak 0 öğesi boş Iolacağından, artırılır).

Yukarıdaki "dört" sabitinin diğer sayılarla değiştirilebileceğini, daha büyük değerlerin genellikle daha az iş etiketlemesi gerektirdiğini, ancak daha küçük değerlerin genellikle daha az iş temizliği gerektirdiğini unutmayın; etiketli dizi yuvalarının temizlenmesi gerektiğinden, üç veya dört değeri neredeyse kesinlikle en uygunudur; Dört değer kesinlikle optimale yakın olduğu için, iki veya sekizden daha iyi olduğu ve diğer herhangi bir sayıdan daha uygun olduğu için, en makul seçim gibi görünecektir.


Tüm hücreler yeni değerlerle güncellenmeden önce yeterli sıralı sıfırlamayı barındırabilen bir sürüm sayacına sahip olmak yeterlidir. Pratikte bir bayt yeterli, hatta daha sıkı döngülerde daha az olabilir.
9000

@ 9000: Bu tür davranışlara dayanan kod kırılgan olmaya eğilimlidir, özellikle bu tür 'sahte açık' bir yaklaşım kullanmanın tek nedeni (sadece diziyi temizlemenin aksine) ihtiyaç duyacağı öğeler kümesi ise Temizlenecek olan tipik olarak küçük ve değişkendir - bir öğenin kullanılma, "temizlenme" ve daha sonra keyfi olarak uzun bir süre dokunulmamış olma olasılığını artırmak için komplo eden bir çift koşul. Sayaç
sarılırken

1
... sayacın sarma değeri sabitse, her dizi temizleme işlemi için ortalama çalışma miktarı O (N) olur; N, dizinin boyutu olur. Böyle bir şey pratikte yararlı olmayabilir, çünkü 65.536 faktörü ile hızlandırılmış bir O (N) uygulaması hala O (N) olacaktır, ancak iyileştirilmemiş olandan 65.536 kat daha hızlı olacaktır. . Bu arada, bu yaklaşımların yardımcı olacağı durumlar, boş olmayan elemanlara sahip bir dizi N boyutuna sahip bir diziyi tutmak için O (AlgN) alanını kullanabilen seyrek dizi veri yapısını kullanmaktan da yararlanabilir.
supercat

1

Ben buna "tembel dizi hücre yeniden başlatma" derdi, ama herhangi bir yerleşik adı (yani, adı geniş kullanımda olmak) görünmüyor.

Algoritma akıllıdır, ancak çok uzmanlaşmış ve çok dar bir alanda uygulanabilir.


1

Bu durumun, küresel sayacın her bir artışıyla birlikte "notlar" dolaylı olarak "yaş" dışında, özel bir notlama durumu olduğuna inanıyorum . Sanırım bir çeşit "geriye doğru hatırlama".

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.