Jak pracować z bardzo długich ciągów znaków w Pythonie?

głosy
5

Ja walce projektowego Eulera problemu 220 (wyglądał łatwe, w porównaniu do niektórych innych - pomyślałem, że spróbować wyższy o numerze jeden na zmiany!)

Do tej pory mam:

D = Fa

def iterate(D,num):
    for i in range (0,num):
        D = D.replace(a,A)
        D = D.replace(b,B)
        D = D.replace(A,aRbFR)
        D = D.replace(B,LFaLb)
    return D

instructions = iterate(Fa,50)

print instructions

Teraz to działa prawidłowo dla niskich wartości, ale gdy mu to powtórzyć wyższe niż po prostu uzyskać „Błąd pamięci”. Czy ktoś może zaproponować sposób na pokonanie tego? Naprawdę chcę się ciąg / plik, który zawiera instrukcje do następnego kroku.

Utwórz 09/12/2008 o 16:35
źródło użytkownik
W innych językach...                            


6 odpowiedzi

głosy
3

Sztuką jest zauważenie, które wyłaniają się wzory jak uruchomić ciąg poprzez każdej iteracji. Spróbuj oceny iterate(D,n)dla n pomiędzy 1 a 10 i sprawdzić, czy można je dostrzec. Również karmić przez ciąg funkcji, która oblicza pozycję końcową i liczbę kroków i szukać wzorców tam.

Można wówczas wykorzystać tę wiedzę w celu uproszczenia algorytmu do czegoś, co nie korzysta z tych ciągów w ogóle.

Odpowiedział 09/12/2008 o 16:57
źródło użytkownik

głosy
2

struny Python nie będą odpowiedzią na ten jeden. Struny są przechowywane jako niezmiennych tablic, więc każda z tych zamienników tworzy zupełnie nowy ciąg w pamięci. Nie wspominając, zbiór instrukcji po 10 ^ 12 kroków będzie co najmniej w rozmiarze 1TB jeśli przechowywać je jako znaki (i to z niewielkimi uciśnięć).

Idealnie, nie powinno być sposobem na matematycznie (wskazówka istnieje) generuje odpowiedź na bieżąco, tak że nie trzeba przechowywać sekwencję.

Wystarczy użyć ciąg jako wytyczne do określenia sposobu, który tworzy swoją ścieżkę.

Odpowiedział 09/12/2008 o 18:42
źródło użytkownik

głosy
2

Jeśli myślisz o tym, jak wielu „A” i „B” znaki istnieją w D (0), D (1), etc, to zobaczymy, że ciąg staje się bardzo długo, bardzo szybko. Oblicz, ile znaków znajduje się w D (50), a potem może znowu myśleć o tym, gdzie chcesz zapisać, że wiele danych. Robię to 4,5 * 10 ^ 15 znaków, co jest 4500 TB na jednym bajcie na char.

Przyjdź, aby myśleć o tym, że nie trzeba obliczać - problem powie istnieje 10 ^ 12 stopni, co najmniej, co jest terabajt danych w jeden bajt na znak lub kwartału, że jeśli używać sztuczek, aby dostać w dół do 2 bitów na znak. Myślę, że to mogłoby spowodować problemy z limitem czasowym jednej minuty na jakimkolwiek nośniku Mam dostęp do :-)

Odpowiedział 09/12/2008 o 16:51
źródło użytkownik

głosy
1

Podobnie jak słowo ostrzeżenia należy zachować ostrożność podczas korzystania z funkcji replace (). Jeśli struny są bardzo duże (w moim przypadku ~ 5E6 znaków) funkcja zastąpić zwróci podzbiór struny (około ~ 4E6 znaków) bez rzucania żadnych błędów.

Odpowiedział 08/11/2011 o 21:02
źródło użytkownik

głosy
1

Ponieważ nie można urzeczywistnić ciąg, należy go wygenerować. Jeśli wydajność poszczególne znaki zamiast powrocie cały ciąg, można zmusić go do pracy.

def repl220( string ):
    for c in string:
        if c == 'a': yield "aRbFR"
        elif c == 'b': yield "LFaLb"
        else yield c

Coś takiego zrobi wymianę bez tworzenia nowego łańcucha.

Teraz, oczywiście, trzeba nazwać rekurencyjnie, a do odpowiedniej głębokości. Tak więc, każdy wydajność to nie tylko wydajność, to coś nieco bardziej skomplikowane.

nie stara się rozwiązać to dla ciebie, więc zostawię go na to.

Odpowiedział 09/12/2008 o 16:56
źródło użytkownik

głosy
0

można traktować jako plik D strumienia bajtów.

Coś jak:-

seedfile = otwartym ( 'D1.txt', 'W'); seedfile.write ( "fa"); seedfile.close (); n = 0, a (n

ostrzeżenie całkowicie niesprawdzone

Odpowiedział 09/12/2008 o 17:40
źródło użytkownik

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