Birçok özdeş tuşlar için en etkili sıralama algoritması?

oy
8

Aşağıdaki verilen bir küme halinde bir araya aynı öğeleri gruplandırma için en verimli bir algoritma ne:

  1. Hemen hemen tüm öğeler birkaç kez yinelenir.
  2. ürün mutlaka tamsayılar veya benzer basit başka bir şey değildir. tuşların aralığı bile iyi tanımlanmış değildir, yalnız küçük edelim. Aslında, tuşlar keyfi yapılar olabilir. Bu tür sayma en basit formları yönetir.
  3. Biz asimptotik olmayan asimptotik özellikleri hem umurumda ve n bazen küçük olabilir. n küçük olduğunda bu fonksiyon küçük veri setleri milyonlarca bir döngü içinde birkaç milyon kez çağrılabilir çünkü ancak performans hala önemlidir. Bu, herhangi bir pahalı karma işlev ya da bellek ayırma çok gerçekleştirmek için gereken bir karmaşık veri yapısı kullanılarak yönetir.
  4. Veri sürece tüm özdeş ürün gruplanmış olarak isteğe göre bir sırada düzenlenmiş olabilir.

Bu kafa karıştırıcı, burada böyle bir işlev groupIdentical adlı varsayarak bir örnek:

uint[] foo = [1,2,3,2,1,5,4,5];
uint[] bar = groupIdentical(foo);
// One possibile correct value for bar:
// bar == [2,2,1,1,3,4,5,5].
// Another possible correct answer:
// bar == [1,1,2,2,5,5,4,3].

Ancak, bir hatırlatma olarak, biz veri tamsayı olarak oluştuğunu kabul edemeyiz.

Düzenleme: Cevaplar için teşekkür ederiz. karma benim ana sorun karma tabloları sıkça için bellek ayırmalarını gerçekleştirmek olmasıydı. Ne yaptığını sona erdi ben bu sorunu aşmanın etrafında olan bir bölge ayırıcısı kullanır kendi karma tablo yazma oldu. İyi çalışıyor.

Oluştur 09/12/2008 saat 22:00
kaynak kullanıcı
Diğer dillerde...                            


9 cevaplar

oy
10

Gerçek sırası önemli olmadığı için, sadece gruplama, sadece nesneleri karma düşünüyorum. Özdeş nesnelerin aynı kovada gruplandırılmış sona erecek. Bu ilgilendiğiniz her türünün kendi karma işlevi vardır varsayarak, veya kendi tanımlayabilir ve (farklı hashCode işlevi tanımına parametre olarak her tür alarak) onu aşırı yüklenmeye neden olabilir.

(Bir örneğin iki katına kadar dizeleri aynı kovada sona kalmamak) veri türleri arasında çakışmaları önlemek için, karma içine veri türünü kodlamak gerekiyordu. Eğer 32 bit karma varsa aynı karma haritasında 32 farklı türleri vardır, böylece Yani, örneğin, belki ilk 5 bit, veri türü kodlamak olabilir.

DÜZENLEME: Bana sadece seni her kova dışında değerlerini elde etmek için iç uygulama yeterli ortaya birinin bilmiyorum çünkü özel bir karma harita öneriyorum nedeni olduğunu ekleyelim. Ben bilmiyorum bu tür bir uygulama olabilir. Bilmiyorum bir çok şey vardır. :)

Cevap 09/12/2008 saat 22:04
kaynak kullanıcı

oy
4

Burada aradığınız sihirli kelimedir multiset (veya torba ). Eğer sürece gruplanmış eşit tuşlarıyla tüm unsurları olduğu gibi sırayla umurumda değil, çünkü gerçekten hiç bir çeşit değil. Orada birkaç konserve uygulamaları kullandığınız dile bağlı olarak, kullanılabilir, ancak genel olarak yukarıda karma sürümü, ben sonu§urda en inanıyorum edilir: insert()Eğer bir karmaşa hesaplar beri sürekli zamandır (1) O ve çarpışan insert ekleme bir liste O (1) zaman; İçinde bidonları bir elementi alabilirsiniz O (1) zaman, sadece çöpe ilkini yakala; ve bu nedenle de hepsini toplayabilir O (n) Eğer almak beri, zaman n ile elementler (1) O , her element için.

Cevap 09/12/2008 saat 23:17
kaynak kullanıcı

oy
3

Böyle python yerleşik sıralama (cf gibi bir dörtnala mergesort, timsort sen O atlarsınız (log (-), önceden sıralanmış veri (gibi, örnekte, aynı nesneler) büyük ishal olduğunda iyi beklenen performansa sahiptir K)) birleştirme başına çalışır. Sizin veri kümesi çok büyük olduğu durumlarda da (bu bir "dış" tür olarak adlandırılır), çoklu CPU ve diskler boyunca bir mergesort dağıtabilir. Bununla birlikte, en kötü durumda O (nlog (N)) olacaktır.

Daha hızlı nlog (N) daha sadece sıralar tuşların bazı yaygın özelliğini istismar türlü, güveniyoruz. Lineer zaman sıralama (karma tablo veya sayı tabanı / kova sıralama) kullanmak için, sayısal anahtarın çeşit üretmek için yapı en karma gerekecek.

onun beklenen zaman bir hashtable yaklaşımından daha uzayacak basamağa göre sıralama, anahtarlar çoklu geçiş yapacak; Eğer lexicographic sırayla umurumda değil çünkü anahtarları karma yapabiliyor ve eğer, karma tablo çözümü, sizin için iyi geliyor.

Cevap 09/12/2008 saat 22:10
kaynak kullanıcı

oy
1

I = haritalama (0.0 aynı şey -0,0 için karma olmayabilir, ama onlar "eşit" olabilir) operatörü koruyan bir karma olduğunu varsayarak, kova içine karma en iyi çözüm olacağını düşünüyoruz. Yalnızca sahip varsayarsak eşit ve Küçüktür operatörü, sen pivot olarak ilk öğesini seçmek ve bir grupta daha az koyarak bir ilkel hızlı sıralama algoritması uygulayabilir ve bu başka bir grup içinde daha büyük ve daha sonra tekrar her bir grup işlem.

Cevap 09/12/2008 saat 22:16
kaynak kullanıcı

oy
1

3-yollu QuickSort çok iyi çiftleri sayıda olduğunda gerçekleştirir.

Cevap 09/12/2008 saat 22:14
kaynak kullanıcı

oy
0

O performansı için Basit algoritması (n (n-1) / 2) aşağıdaki gibidir:

  1. n gibi giriş sahip boyut olarak adlandırılan giriş dizi varsayalım.
  2. Sonuç olarak adlandırılan aynı boyutta dönüş dizisi için bir bellek ayır
  3. Ziyaret etti ve set olarak adlandırılan aynı boyutta Boole dizisi için bir bellek ayır tüm yanlış olarak Visted
  4. Her iki ürün sahte başka eşitse return true Eşittir olarak adlandırılan bir Eşit işlevi vardır varsayalım.
  5. Varsayalım dizi indeksi 1 ile n arasında başlar
  6. Aşağıda Sözde C kodu bakın:
function groupIdentical(Input) 
{
    k=1;
    for i=1 to n 
    {
        Visited[i]=false ;
    }

    for i=1 to n
    {
        if( !Visited(i) )
        {   
            Result[k++]=Input[i];
            for j= (i+1) to n
            {
                if( Equals(i,j) )
                {
                    Result[k++]=Input[j];
                    Visited[j]=true;
                }   
            }
        }
    }
    return Result;
}
Cevap 10/12/2008 saat 08:16
kaynak kullanıcı

oy
0

Belki bir R + B veya AVL ağacı? Sonra tekrar - Hala sonuçta O (NlogN) olacaktır. yanı Heapsort kullanabilir - daha kötü ve hiçbir ekstra bellek kullanımı olmayacak ...

Cevap 09/12/2008 saat 22:36
kaynak kullanıcı

oy
0

Ben size etrafında çok fazla kopya istemiyoruz keyfi nesneler beri, sadece sıralama için referanslar veya işaretçileri kullanın ve gerekirse sonradan sırayla nesneleri kopyalamak düşünüyorum.

Cevap 09/12/2008 saat 22:19
kaynak kullanıcı

oy
0

Eğer olası değerler aralığında biliyoruz ve o küçük ise, yapabileceği: (sözde imsi kodu)

uint[] bucket = new int[10];
foreach(uint val in foo) {
    ++bucket[val];
}

uint bar_i = 0;
uint[] bar = new int[foo.length];
foreach(int val = 0; val < 10; val++) {
    uint occurrences = bucket[val];
    for(int i=0; i < occurrences; i++) {
        bar[bar_i++] = val;
    }
}
Cevap 09/12/2008 saat 22:16
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more