Sen muhtemelen, hafifçe indi yok quantlar temel algoritmalar anlamıyorum hedge fonu için çalışan olmak istiyorum :-)
Orada hiçbir bir keyfi boyutlu veri yapısını işlemek için bir yol O(1)
bu durumda olduğu gibi, bir kez en az her eleman ziyaret gerekir, eğer. En iyi için umut olabilir olduğunu O(n)
bu durumda, içinde n
dize uzunluğudur.
Bir kenara olarak, nominal rağmen O(n)
algoritma olacak olması O(1)
bu yüzden, teknik olarak sabit bir giriş boyutu için, burada doğru olmuş olabilir. Ancak, genellikle karmaşıklık analizini bu şekilde kullanmazlar.
Bana öyle geliyor ki onları çeşitli şekillerde etkilemiş olabilirsiniz.
İlk olarak, yukarıda verilen "şüpheli" muhakemeyi kullanmadığınız sürece, bunu yapmanın mümkün olmadığını bildirerek O(1)
.
İkincisi, elit becerilerinizi aşağıdaki gibi Pythonic kodu sağlayarak göstererek:
inpStr = '123412345123456'
# O(1) array creation.
freq = [0] * 1000
# O(n) string processing.
for val in [int(inpStr[pos:pos+3]) for pos in range(len(inpStr) - 2)]:
freq[val] += 1
# O(1) output of relevant array values.
print ([(num, freq[num]) for num in range(1000) if freq[num] > 1])
Bu çıktılar:
[(123, 3), (234, 3), (345, 2)]
tabii ki çıktı formatını istediğiniz gibi değiştirebilirsiniz.
Ve son olarak, onlara bir çözümle neredeyse hiç sorun olmadığını söyleyerek O(n)
, yukarıdaki kod yarım saniyenin altında bir milyon basamaklı bir dize için sonuçlar verir. 10.000.000 karakterlik bir dize 3.5 saniye ve 100.000.000 karakterlik bir 36 saniye sürdüğü için oldukça doğrusal olarak ölçeklendirilmiş gibi görünüyor.
Ve bundan daha iyisine ihtiyaç duyarlarsa , bu tür şeyleri büyük ölçüde hızlandıracak paralel hale getirmenin yolları vardır.
Tabii ki, GIL nedeniyle tek bir Python yorumlayıcısı içinde değil , ancak dizeyi benzer bir şeye bölebilirsiniz ( vv
sınır alanlarının düzgün işlenmesine izin vermek için belirtilen örtüşme gerekir):
vv
123412 vv
123451
5123456
Bunları işçileri ayırmak ve daha sonra sonuçları birleştirmek için toplayabilirsiniz.
Girdinin bölünmesi ve çıktının birleştirilmesi muhtemelen küçük dizelerle (ve hatta milyon haneli dizelerle) herhangi bir tasarrufu azaltacaktır, ancak çok daha büyük veri kümeleri için fark yaratabilir. Burada her zamanki "ölçmek, tahmin etmemek" mantrası geçerlidir.
Bu mantra , Python'u tamamen atlamak ve daha hızlı olabilecek farklı bir dil kullanmak gibi diğer olasılıklar için de geçerlidir .
Örneğin, önceki Python koduyla aynı donanımda çalışan aşağıdaki C kodu, 0,6 saniyede yüz milyon basamağı işlemektedir , yaklaşık olarak Python kodunun bir milyon işlediği süre . Başka bir deyişle, çok daha hızlı:
#include <stdio.h>
#include <string.h>
int main(void) {
static char inpStr[100000000+1];
static int freq[1000];
// Set up test data.
memset(inpStr, '1', sizeof(inpStr));
inpStr[sizeof(inpStr)-1] = '\0';
// Need at least three digits to do anything useful.
if (strlen(inpStr) <= 2) return 0;
// Get initial feed from first two digits, process others.
int val = (inpStr[0] - '0') * 10 + inpStr[1] - '0';
char *inpPtr = &(inpStr[2]);
while (*inpPtr != '\0') {
// Remove hundreds, add next digit as units, adjust table.
val = (val % 100) * 10 + *inpPtr++ - '0';
freq[val]++;
}
// Output (relevant part of) table.
for (int i = 0; i < 1000; ++i)
if (freq[i] > 1)
printf("%3d -> %d\n", i, freq[i]);
return 0;
}