Hangi algoritmaları / veri yapılarını “tanımalı” ve isimle bilmeliyim? [kapalı]


69

Kendimi oldukça deneyimli bir programcı olarak görmek isterim. Şimdi 5 yıldır program yapıyorum. Benim zayıf noktam terminoloji. Kendi kendime öğrendim, bu yüzden nasıl programlanacağını bilmeme rağmen, bilgisayar biliminin daha resmi yönlerini bilmiyorum. Peki, ismiyle tanıyabildiğim ve tanıyabileceğim pratik algoritmalar / veri yapıları nelerdir?

Not, algoritmaları uygulama hakkında bir kitap önerisi istemiyorum. Bunları uygulama umurumda değil, sadece bir algoritma / veri yapısının bir soruna iyi bir çözüm olacağını bilmek istiyorum. Daha fazla "tanımak" gereken algoritmaların / veri yapılarının bir listesini istiyorum. Örneğin, böyle bir sorunun çözümünü biliyorum:

0-999 etiketli bir dolap seti yönetiyorsunuz. Soyunma odasını kiralamak için insanlar gelir ve soyunma anahtarını geri göndermek için gelir. Hangi dolapların ücretsiz olduğunu ve hangilerinin kullanıldığını bilmek için nasıl bir yazılım geliştirirsiniz?

Çözüm, bir sıra veya yığın olurdu.

Aradığım şey "B-Ağacı hangi durumda kullanılmalı - Hangi arama algoritmasının burada kullanılması gerektiği" vs. gibi şeylerdir. algoritmalar çalışır.

Vikipedi'nin veri yapıları ve algoritmaları listesine bakmayı denedim, ancak bunun biraz daha fazla olduğunu düşünüyorum. Öyleyse daha iyi bakmalıyım, tanımam gereken temel şeyler neler?


10
"Yapıcı değil" olarak kapatmak için oy kullanma. Herhangi bir cevap tamamen öznel olacaktır - birinin "bilmesi" gerektiği konusunda fikir birliği yoktur.
Oded

2
Bu soyunma sorununun hangi kısmı giriş / çıkış siparişi gerektiriyor? [ipucu!]
Telastyn

5
@Oded kesinlikle çoğu insanın iyi niyetli bir programcının bilmesi gereken veri yapıları ve algoritmaları için hemfikir olacağına inanıyorum.
David Cowden,

6
@Oded konsensüs yok mu? Bilgisayar bilimindeki algoritmalar ve veri yapıları üzerine giriş kursunun müfredatına ne dersiniz? Oldukça iyi standardize edilmiş ve meslektaş gözden geçirilmiştir . İyi bir başlangıç ​​noktası.
MarkJ

3
Alternatif çözüm; günlük ücret aldığınızı ve maksimum ücret aldığınızı varsayalım. Dolabı bırakıp üzerine Julian günü numarasını yazarken tuşa bir kağıt etiket yapıştırın. Anahtar iade edildiğinde, ödenecek kirayı hesaplamak için etikete bakın. Eksik veya bozuk etiketler maksimum yükü çeker. Kullanılmayan anahtarlar bir çantada saklanır (bir dolabı bırakırken serbest anahtarlardan herhangi bir anahtar seçmeye gerek olmadığından). Toplam veri yapısı boyutu: sıfır bit. Algoritmanın tüm parçaları O (1).
James Youngman

Yanıtlar:


78

Nesnel bir cevap:

Bu soruya ilk tepkim, kısa süre önce mezun olacak bir CS öğrencisi olarak deneysel deneyimlerime ve CS alanında çalışmak istediğim kişilerin türü hakkında öngörüldüğü düşünceme dayanıyordu. Aslında (ACM SIGCSE ve IEEE bilgi işlem topluluklarının öznel görüşleri ile ilgili) bir hedefi var. Her 10 yılda bir ACM ve IEEE organları , bilgisayar endüstrisi durumunun mesleki bilgisine dayalı lisans bilgisayar bilimi müfredatı için önerileri ayrıntılandıran ortak bir yayın üzerinde işbirliği yapıyor . Daha fazla bilgi cs2013.org adresinde bulunabilir . Komite , müfredat önerilerini listeleyen son bir rapor yayınlar .

Dedi ki, hala listemin oldukça iyi olduğunu düşünüyorum.

Aşağıdaki orijinal cevap.


Ne Bilmeliyim?

minimum

Ben bir usta programcı Bilgisayar Bilimi alanında en az lisans düzeyinde bilgiye sahip olması gerektiğini düşünüyorum. Tabii ki, CS küçük bir topluluk oturduğu ve çoğu profesyonel pozisyonların daralmış odağı nedeniyle, yalnızca küçük bir Bilgisayar Bilimi alt kümesi olan birçok işte etkili olabilirsiniz . Ayrıca, birçok kişi lisans eğitimi sonrasında uzmanlaşacaktır. Bununla birlikte, temel CS bilgisine özgü olmamak için mazeret olmadığını da düşünüyorum.

Başlık sorusunu cevaplamak için, bir lisans CS öğrencisi (usta bir programcının temeli) mezuniyet sırasında bilmesi gerekenler:

Veri Yapıları

  • Makine Veri Sunumu
    • Birler, İkinin Tamamlayıcıları ve İlişkili Aritmetik
    • Kelimeler, İşaretçiler, Kayan Nokta
    • Bit Erişim, Vites Değiştirme ve Manipülasyon
  • Bağlantılı Listeler
  • Karma Tablolar (haritalar veya sözlükler)
  • Diziler
  • Ağaçlar
  • Yığınlar
  • Kuyruklar
  • Grafikler
  • Veritabanları

Algoritmalar

  • Sıralama:
    • Kabarcık Sıralaması (neden kötü olduğunu bilmek)
    • Ekleme Sıralaması
    • Sıralama Birleştir
    • Hızlı sıralama
    • Radix stili sıralama, Sıralama ve Kova Sıralama
    • Öbek Sıralama
    • Bogo ve Kuantum Sıralama (=
  • Aranıyor:
    • Doğrusal Arama
    • Ikili arama
    • Derinlik öncelikli arama
    • Genişlik İlk Arama
  • Dize Manipülasyonu
  • tekrarlama
  • Ağaç Geçişi
  • Geçişi Listele
  • Hashing İşlevleri
  • Karma Tablo, Ağaç, Liste, Yığın, Sıra, Dizi ve Küme veya Koleksiyonun somut uygulaması
  • Çizelgeleme Algoritmaları
  • Dosya Sistemi Geçişi ve Manipülasyonu ( inode veya eşdeğeri bir seviyede).

Tasarım desenleri

  • modularization
  • Fabrika
  • inşaatçı
  • Singleton
  • adaptör
  • Dekoratör
  • sineksiklet
  • Gözlemci
  • yineleyici
  • Devlet [Makine]
  • Model Görünümü Kontrolörü
  • Diş Açma ve Paralel Programlama Kalıpları

Paradigmalar

  • Zorunlu
  • Nesne odaklı
  • Fonksiyonel
  • bildiren
  • Statik ve Dinamik Programlama
  • Veri İşaretlemesi

Karmaşıklık Teorisi

  • Karmaşıklık Uzayları
  • hesaplanabilirlik
  • Düzenli, Bağlamsız ve Evrensel Turing Makinesi tamamlandı Diller
  • Düzenli ifadeler
  • Sayma ve Temel Kombinatorik

ötesinde

Sorunuzda sormak istediklerinize ulaşmak için, yukarıdakilere aşina iseniz, belirli bir senaryo için uygun modeli, algoritmayı ve veri yapısını kolayca tanımlamanız gerekir. Ancak, çoğu zaman en iyi çözümü olmadığını kabul etmelisiniz. Bazen iki kötülüğün daha azını seçmeniz ya da eşit derecede uygulanabilir iki çözüm arasından seçim yapmanız gerekebilir. Bu nedenle, seçiminizi meslektaşlarınıza karşı savunabilmek için genel bilgiye ihtiyacınız var.

Algoritmalar ve veri yapıları için bazı ipuçları:

  • İkili Arama yalnızca sıralanmış verilerde kullanılabilir (ve gerekir).
  • Radix tarzı türler harika, ancak yalnızca sıralanan şeylerin sınırlı sınıflarına sahip olduğunuzda.
  • Ağaçlar, Hash Table'lar gibi hemen hemen her şey için iyidir. Bir Hash Tablosunun işlevselliği, fazla maliyetle birçok sorunu çözmek için tahmin edilebilir ve kullanılabilir.
  • Diziler, çoğu üst düzey veri yapısını desteklemek için kullanılabilir. Bazen bir "veri yapısı", bir dizideki konumlara erişmek için akıllı bir matematikten daha fazla değildir.
  • Dil seçimi, saçınızı bir kenara çekmek veya bir şeyle dolaşmak arasındaki fark olabilir.
  • ASCII tablosu ve 128 eleman dizisi, örtük bir karma tablo oluşturur (=
  • Normal ifadeler birçok sorunu çözebilir, ancak HTML'yi ayrıştırmak için kullanılamaz .
  • Bazen veri yapısı algoritması kadar önemlidir.

Yukarıdakilerin bazıları beyinsiz gibi görünebilir ve bazıları belirsiz görünebilir. Daha fazla ayrıntıya girmemi istiyorsan, yapabilirim. Ancak, umudum, "Bir Dize'deki her karakterin oluşumunu sayan bir işlev tasarla" gibi daha somut bir soru ile karşılaştığımızda, ASCII tablosu ile ilgili ipucuna ve düzgün bir karma değer yaratan 128 eleman dizisine bakıyorsunuzdur. cevap için tablolar.

Bu düşüncelere dayanarak, sorunuzda belirtilen soyunma sorununa bir cevap önereceğim.


Sorunuza sorulan soruna cevap.

Sorunuza en iyi cevap olmayabilir ama bence çok karmaşık bir şey gerektirmeyen ilginç bir cevap. Ve kesinlikle bir dolabın serbest olup olmadığını belirlemek için doğrusal zaman gerektiren bir kuyruk veya yığın kullanmanın zaman karmaşıklığını yenecektir.

0-999 dolabın var. Şimdi, sabit sayıda kilitli dolabınız olduğundan, 0-999 aralığında hiçbir çarpışma olmadan kolayca bir karma fonksiyonunu düşünebilirsiniz. Bu işlev basitçe h (x) = x mod 1000'dir. Şimdi, [kavramsal olarak] tamsayı tuşları ve 1000 element char dizisinin içeriğini değerleriniz olarak içeren bir karma tablo oluşturur. Bir müşteri kullanım 78 dolabını kullanım için rezerve etmek istiyorsa, sadece 78 işlevini karma fonksiyonuna koyun (78 döndürür) ve sonra bu sayıyı dizinin temel göstergesine ekleyin - ofset değerinin gösterdiği yerde gerçek bir değer saklayın . Benzer şekilde, 78'in kullanımda olup olmadığını kontrol etmeniz gerekiyorsa, sadece o yerde kayıtlı olan değeri okuyun ve doğru olup olmadığını kontrol edin.

Bu çözüm, günlük (n) zaman deposunun aksine, ikili bir ağaç tarafından desteklenen öncelik sırası kuyruğunda arama ve depolama için sabit zamanda çalışır. Tanım kasıtlı olarak ayrıntılıdır, böylece daha yüksek kavramların etkin bir algoritmaya dönüştürüldüğünü görebilirsiniz.

Şimdi, mevcut tüm dolapları bilmem gerekirse, öncelik sırasının daha iyi olmaması için ne isteyebilirsiniz? Öncelik kuyruğunda k mevcut dolap varsa, hepsini yinelemek k adımlarını atar. Dahası, öncelik sırası uygulamanıza bağlı olarak, hepsine bakarken öncelik sıranızı yeniden oluşturmanız gerekebilir .. ki bu k * log (k): (k <1000) adım atar. Dizi çözümünde, yalnızca 1000 elemanlı bir diziyi yinelemeniz ve hangilerinin açık olduğunu kontrol etmeniz yeterlidir. Ayrıca sadece k zamanında check-in yapmak için uygulamaya bir kullanılabilir veya kullanılmış liste ekleyebilirsiniz.


1
Mükemmel cevap! Ayrıca, kullandığınız dilin önceden tanımlanmış işlevlerini / veri yapılarını, örneğin C ++ 'da algoritma ve stl veri yapıları veya Java için Java API'sini kullanırken kendinize güvenmeniz gerektiğini de eklemek isterim.
marktani

1
Mükemmel! Özellikle "Normal ifadeler birçok sorunu çözebilir, ancak HTML'yi ayrıştırmak için kullanılamaz."
SinirliFormsDesigner ile

2
Cevap, "sorun" görünene kadar iyiydi. Öncelikli bir sıra veya karma tablo kullanmak için hiçbir neden yoktur. Basit bir yığın yeterlidir. İsterseniz ücretsiz dolap tam listesini almak için yineleme ekleyin.
Matthieu M.,

1
ilişkisel veritabanı + SQL, B + ağacı bilgisi, derleyici teorisi, bilgi donanımı organizasyonu, işletim sistemi teorisi bilgisi, TCP / IP ağı bilgisi eklenmeli midir?
dan_l

1
Tasarım Desenleri konusunda şüpheliyim. Birçoğu bazı dillerde yararlı olurken, bazılarında gereksiz ve / veya gereksiz. Ayrıca algoritmalar altında Sezgisel tarama eklemek ve veri yapılarını listelemek ve atlamak isteyebilirsiniz. Geleneksel algoritmalar / veri yapıları senkron erişimde bir sınıra ulaşır, ancak çoklu iş parçacığı ve eşzamanlılık kullanan diğer geleneksel olmayan yaklaşımlarla yenilebilir. Sezgisel tarama, ihtiyaç duyulan arama sayısını önemli ölçüde azaltabilirken, atlama listesi gibi yapılar veri yapısının genel bir kilitlenmeden yazılmasını sağlar.
Evan Plaice

6

Steven S. Skiena'nın Algoritma Tasarım El Kitabı , aradığınız kaynak gibi görünüyor. İkinci bölüm, ilgili algoritmaların gözden geçirilmesi ile sınıflandırılmış bir sorun listesidir. Bir web versiyonu var .


3
Harika bir kitap, ama gerçekten bir programcı olmak için hepsine hakim olmak zorunda hissetmeyin. Daha yeni yeni aldım ve 1979'dan beri programa para aldım. (Ve evet, ondan bir şey öğrenebileceğime inandım.)
Kate Gregory

@KateGregory Kitabı satın aldım ve kitabı gerçekten alamadım, çünkü yalnızca Ruby ve Javascript gibi yüksek seviye dilleri biliyorum (ikili ağaçlar, bağlantılı listeler yok, vs.) ... Sonunda onu okumaktan vazgeçtim.
bigpotato '

4

"Olması gereken" yok. A. Temel karmaşıklık sınıfları (doğrusal, logaritmik, vb.) İle tanışın. B. Basit bir diziyle, B ağacı gibi süslü bir veri yapısıyla yapabileceğiniz her şeyi yapabileceğinizi fark edin. Uygun yapı / algoritmayı seçmenin püf noktası, dengeleme performansı, beklenen girdi büyüklüğü ve uygulama karmaşıklığıdır.

Sonra soyut ama son derece yararlı şeyler var (faydalılık hemen belli olmasa da): durum makineleri, grafik teorisi, dışbükeylik teorisi (doğrusal programlama, vb.).


1
Ne zaman kullanılacağını bilmenin önemini küçümsemeyin. Çünkü basit bir dizi kullanarak çözdüğünüz problemler geri gelecek ve tam da o büyük müşteriyi ele geçirmek üzereyken sizi ısırmaya başlayacak ve yıllarca iyi çalışan uygulamanızı sadece bir baloncuk yerine kullandığınız için bir taramaya yavaşlatacağız. bir hızlı bağlantı.
Pieter B,

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.