Nasıl iki liste dairesel Python ile aynı olup olmadığını kontrol etmek için
Örneğin, bir listem var:
a[0] = [1, 1, 1, 0, 0]
a[1] = [1, 1, 0, 0, 1]
a[2] = [0, 1, 1, 1, 0]
# and so on
Farklı gibi görünüyor, ama eğer başlangıç ve bitiş bağlı olduğu tahmin ediliyor, o zamandaireselaynı.
Sorun, var olan her liste 55 uzunluğa sahiptir ve sadece üç birler ve sıfırlar 52 içerir. Dairesel koşul olmadan, 26,235 (3 seçmek 55) listeleri vardır. Bu durum ancak, 'döngüsel', dairesel aynı listelerinin çok sayıda var
Şu anda takip ederek dairesel kimliğini Gözden geçirdim
def is_dup(a, b):
for i in range(len(a)):
if a == list(numpy.roll(b, i)): # shift b circularly by i
return True
return False
Bu işlev, en kötü ihtimalle 55 döngüsel shift işlemleri gerektirir. Ve birbirleri ile karşılaştırılmak 26,235 listeleri vardır. Kısacası, 55 * 26,235 * (26,235 - 1) / 2 = 18,926,847,225 hesaplamaları lazım. Yaklaşık 20 Giga!
Herhangi bir iyi bir yol daha az hesaplamaları ile ilgisi var mı? Ya da destekleyen herhangi bir veri türleridairesel?
CEVAP
Öncelikle, bu listenin uzunluğu bakımından O(n)
yapılabilir
Eğer 2 kez ([1, 2, 3]
) [1, 2, 3, 1, 2, 3]
olacak listenizi çoğaltmak istersen o zaman yeni bir liste kesinlikle tüm olası döngüsel listeleri düzenleyecek dikkat edin.
Tüm aradığınız listesi başlangıç listesinden 2 kez içinde olup olmadığını kontrol etmektir. Python şu şekilde (uzunlukları aynı olduğunu varsayarsak) bunu elde edebilirsiniz.
list1 = [1, 1, 1, 0, 0]
list2 = [1, 1, 0, 0, 1]
print ' '.join(map(str, list2)) in ' '.join(map(str, list1 * 2))
Benim oneliner ilgili bir açıklama:
list * 2
kendisi ile ilgili bir liste birleştirir, map(str, [1, 2])
dize için tüm numaraları dönüştürmek ve ' '.join()
bir dizeye 14* *dizi '1 2 111'
dönüştürür.
Yorumlarda bazı kişiler tarafından işaret olarak, oneliner Olası bazı yanlış pozitif sonuç verebilir, tüm olası kenar taleplerini karşılamak için:
def isCircular(arr1, arr2):
if len(arr1) != len(arr2):
return False
str1 = ' '.join(map(str, arr1))
str2 = ' '.join(map(str, arr2))
if len(str1) != len(str2):
return False
return str1 in str2 ' ' str2
P. S. 1zaman karmaşıklığı hakkında konuşurken, eğer alt O(n)
zaman bulunabilir O(n)
elde edilebileceğini fark değer. Her zaman böyle değildir ve dil (although potentially it can be done in linear zaman örneğin KMP) uygulamasına bağlıdır.
P. S. 2ve bu gerçek yüzünden korkuyor dizeleri ameliyat olan insanlar cevap değil iyi olduğunu düşünüyorum. Önemli olan ne karmaşıklık ve hız. Bu algoritma Olası O(n)
ve O(n^2)
etki alanı içinde her şeyi daha iyi yapar O(n)
uzayda çalışır. Kendiniz görmek için, (rasgele bir liste oluşturur ilk öğe açılır ve sonunda böylece döngüsel bir listesini oluşturmak için ekler. küçük bir kriter çalıştırabilirsiniz Kendi manipülasyonlar yapmak) için ücretsiz
from random import random
bigList = [int(1000 * random()) for i in xrange(10**6)]
bigList2 = bigList[:]
bigList2.append(bigList2.pop(0))
# then test how much time will it take to come up with an answer
from datetime import datetime
startTime = datetime.now()
print isCircular(bigList, bigList2)
print datetime.now() - startTime # please fill free to use timeit, but it will give similar results
Benim makinede 0.3 saniye. Çok uzun değil. Şimdi O(n^2)
çözümler ile bu karşılaştırmak için deneyin. Karşılaştırma sırasında, Avustralya (büyük olasılıkla bir yolcu gemisi tarafından) BİZE gelen seyahat edebilirsiniz
Eğer kullanıcı giriş olup olmadığını k...
Nasıl Python ile bir dize ASCII olup o...
Nasıl eğer bir değeri bir sözlük (pyth...
Eğer listedeki herhangi bir yinelenen ...
Nasıl bir yol mutlak bir yol veya göre...