2011-07-18 22 views
5

Poszukuje szybkiego sposobu ograniczenia duplikatów do maksymalnie 2, gdy występują obok siebie.Usuwanie powtarzających się duplikatów liter

Na przykład: jeeeeeeeep =>['jep','jeep']

Szukam sugestii w Pythonie, ale szczęśliwy, aby zobaczyć przykład w cokolwiek - nie jest trudne, aby przełączyć.

Dzięki za pomoc!

EDYCJA: Angielski nie ma żadnych (lub wielu) spółgłosek (tej samej litery) z prawej strony? Ograniczmy to, aby nie było duplikatów spółgłosek z rzędu i maksymalnie dwóch samogłosek z rzędu.

EDIT2: Jestem głupi (hej, to słowo ma dwie spółgłoski), po prostu sprawdzam wszystkie litery, ograniczając duplikaty liter, które są obok nawzajem do dwóch.

+0

W którym momencie w programie starasz się ograniczyć ten ? Jak użytkownik wprowadza coś lub później? Jak wygląda wejście? Tylko jedno słowo lub cały ciąg z możliwością wielu dopasowań? –

+1

Jaki powinien być wynik dla "jjjjeeeeppppp"? –

+0

@elmugrat - w zasadzie chodzi o sprawdzanie pisowni, ale nie jest on w locie, więc naprawiłbym go po naciśnięciu "enter" @Ned Teraz, gdy o tym wspomniałeś, chciałbym ograniczyć samogłoski do dwóch i spółgłosek do jednego (dotyczy to języka angielskiego, prawda?), więc wyjście nadal byłoby ['jep', 'jeep'] dobrym pomysłem, że specyfikacja musiała być widoczna – jphenow

Odpowiedz

3

Oto rekurencyjny rozwiązanie wykorzystujące groupby. Zostawiłam ją do siebie, które znaki chcesz być w stanie powtórzyć (domyślnie tylko samogłosek choć):

from itertools import groupby 

def find_dub_strs(mystring): 
    grp = groupby(mystring) 
    seq = [(k, len(list(g)) >= 2) for k, g in grp] 
    allowed = ('aeioupt') 
    return rec_dubz('', seq, allowed=allowed) 

def rec_dubz(prev, seq, allowed='aeiou'): 
    if not seq: 
     return [prev] 
    solutions = rec_dubz(prev + seq[0][0], seq[1:], allowed=allowed) 
    if seq[0][0] in allowed and seq[0][1]: 
     solutions += rec_dubz(prev + seq[0][0] * 2, seq[1:], allowed=allowed) 
    return solutions 

to naprawdę tylko heurystycznie przycina głębokość pierwszego wyszukiwania w swojej „przestrzeni” w roztworze możliwe słowa. Hierarchia polega na tym, że dopuszczamy tylko jedno powtórzenie naraz i tylko jeśli jest to ważna powtarzalna litera. Powinieneś skończyć na 2 ** n słowach na końcu, gdzie n jest liczbą razy, gdy "dozwolony" znak został powtórzony w twoim ciągu.

>>> find_dub_strs('jeeeeeep') 
['jep', 'jeep'] 
>>> find_dub_strs('jeeeeeeppp') 
['jep', 'jepp', 'jeep', 'jeepp'] 
>>> find_dub_strs('jeeeeeeppphhhht') 
['jepht', 'jeppht', 'jeepht', 'jeeppht'] 
+0

Zobacz mój poprawiony post - dopracowałem zasady. Spróbuj ograniczyć samogłoski do dwóch w rzędzie i bez duplikatów z rzędu w przeciwnym wypadku. Ma sens? – jphenow

+0

@jphenow: A co z liczbami? Włożył 1111 co jeśli tekst zawiera liczbę, która przypadkowo ma podwójne lub nawet więcej powtórzeń z rzędu? Rozważ numery telefonów, które w tym przypadku byłyby błędne. – Nobody

+0

Nie martwisz się liczbami, ale zredagujesz wypowiedź o spółgłoskach, tylko martwisz się o wszystkie litery – jphenow

-1

Używaj wyrażeń regularnych wraz z kluczowym wydarzeniem prasowym!

+1

Najważniejsze wydarzenie prasowe? – Jacob

+1

Nie sądzę, że chce ograniczyć wejście z klawiatury. – Nobody

0

Oto rozwiązanie Sh + Perl, obawiam się, że nie wiem, Python:

echo jjjjeeeeeeeeppppp | perl -ne 's/(.)\1+/\1\1/g; print $_;' 

Kluczem jest regex, który znajdzie (.)\1+ i zastępuje go \1\1 globalnie.

1

użyć wyrażenia regularnego:

>>> import re 
>>> re.sub(r'(.)\1\1+', r'\1\1', 'jeeeep') 
'jeep' 
1

Rozwiązaniem dla pojedynczego znaku używając groupby:

>>> from itertools import groupby 
>>> s = 'jeeeeeeeep' 
>>> ''.join(c for c, unused in groupby(s)) 
'jep' 

a jeden dla maksymalnie dwóch znaków:

''.join(''.join(list(group)[:2]) for unused, group in groupby(s)) 
Powiązane problemy