2009-11-16 24 views
22

Listenin başına ve sonuna 2 görünüm alabildiğim bir liste veri yapısını verimli bir şekilde uygulayabilirim. yani:Haskell'de etkin bir kuyruk

start x = [] 
end x = reverse start -- [] 
start1 = [1,2,3] ++ start 
end start1 -- [3,2,1] 

uç 'ters' yürütmesini ama sadece otomatik tersten olmanın listenin perspektifinden verilen listeye bakmadan bunu yapmak mümkün olmalıdır. Başlamak için birleştirmelerden yeni listeler oluşturursam da aynısı geçerli olmalıdır.

+1

Haskell'de değerleri değiştiremezsiniz. 'start' her zaman boş liste olacaktır ve' end' her zaman bunun tersi olacaktır (boş liste). Eğer devleti korumak istiyorsan, devlet monadına bakmalısın. –

+1

düzeltme: Güncelleme ile rebind demek istiyorum. – TheOne

+1

@Absolute: buna ne diyorsunuz, Haskell'de bir şeyleri değiştiremeyeceğiniz nihai hakikati değiştiremezsiniz ('IO' monad). Bir şeyleri yeniden ispat edemezsin. –

cevap

34

Her zamanda Data.Sequence kullanabilirsiniz. Tamamen işlevsel bir kuyruğun iyi bilinen bir uygulaması iki liste kullanmaktır. Bir deque ve diğeri dequeue için. Enqueue sadece enqueue listesi ile birlikte olur. Dequeue, dequeue listesinin başını alır. Dequeue listesi boş olduğunda, enqueue listesini tersine çevirerek tekrar doldurun. Bu uygulama reverse kullanıyor olsa da, bu amortize edilmiş zaman maliyeti asimptotik olarak önemsizdir (bkz. Chris Okasaki'nin Purely Functional Datastructures.

). Her bir deger için, dequeue list dolgusu için Θ (1) 'lik bir zaman borcuna maruz kalacaksınız. Bir dequeue'nin beklenen süresi bu nedenle bir değerin iki katıdır. Bu sabit bir faktördür, bu nedenle her iki operasyonun maliyeti de Θ (1).

+14

Önemli değil * sadece * eğer geçici olarak kullanılıyorsa. Uygulamanız sürekliliğe bağlıysa, sıranıza her eriştiğinizde O (n) vakasına girmek tamamen mümkündür. – Juliet

+4

@Juliet Tembellik ve memoizasyon kullanımı ile, amortize edilmiş bağ hala O (1) kalıcılığını korurken – Yuhta

+1

@ Yuhta tembelliği ve hatıraları kullanarak bir örnek gösterebilir misiniz? – CMCDragonkai

1

Ben gerçekten bir Haskell kullanıcısı değilim, ama amortize sabit zamanda çalıştırılabilen bir Haskell kuyruğunu açıkladığı iddia edilen a blog post buldum. Chris Okasaki'nin mükemmel İşlevsel Veri Yapıları'ndan bir tasarıma dayanıyor.

5

Data.Dequeue Ne arıyorsunuz?

(O reverse yok ama oldukça kolayca ekleyebilir ve yazara bir yama gönderebilir.)

+5

Kütüphanenin farkındayım, sadece kendimi eğlenceli bir düşünce deneyi olarak uygulamak istiyorum. – TheOne

+0

Ya da zaten standart kütüphane – newacct

+0

olan 'Data.Sequence 'modülünü kullanabilir ya da onlar yapmak istedikleri gibi onlar gibi eğlenceli bir düşünce deneyi olarak kendiniz uygulayabilirsiniz. Ve bununla ilgili yanlış bir şey yok. – semicolon