Pyrhon - algorytm podzialu napisu na slowa

Pyrhon - algorytm podzialu napisu na slowa
SK
  • Rejestracja:ponad 13 lat
  • Ostatnio:ponad 7 lat
  • Postów:80
0

Czesc, probuje napisac program do wypisania wszystkich podzialow na slowa dowolnego napisu, np. NAPIS=matematykapustkinieznosi.
Napisalem kod, ale mam problem z ostateczym odczytaniem wynikow, dlatego prosilbym Was o pomoc w sprawdzeniu algorytmu.

Z pliku txt pobieram liste rzeczownikow, przy czym w pamieci, w zbiorze SET pozostawiam tylko te, ktore zawieraja sie w napisie NAPIS.
Nastepnie, wybieraz z SET slowo, od ktorego rozpoczyna sie NAPIS. Slowo to jest pierwszym elementem podzialu, wiec nastepnie probuje wyznaczyc (rekurencyjnie) podzial NAPIS z pominietym poczatkiem.
Przykladowo: w matematykapustkinieznosi znalazlem slowo matematyka, wiec szukam dalej rekurencyjnie podzialu na slowa napisu pustkinieznosi.

Kopiuj
zbior_slow = set()

for slowo in set_rzecz:
    if slowo in 'matematykapustkinieznosi':
        zbior_slow.add(slowo)

def podzial_na_slowa(zbior_slow, wyraz):

    podzialy = []
    
    for slowo in zbior_slow:
        if wyraz.find(slowo) == 0:
            podzialy.append(slowo)
            if wyraz[len(slowo):] <> '':
                podzialy.append( podzial_na_slowa( zbior_slow, wyraz[len(slowo):]) )
            
    return podzialy

Wynik funkcji podzial_na_slowa(zbior_slow, 'matematykapustkinieznosi') umiescilem w zalaczniku.
W efekcie dostaje liste zagniezdzona, i po wynikach widac, ze zawiera ona to czego szukam, ale nie potrafie juz w przyjazny sposob wyswietlic wynikow, czyli np.

Kopiuj
matematyka-pustki-nie-znosi
ma-tematyka-pustki-nie-znosi

Czy macie moze jakis pomysl jak moznaby poprawic algorytm albo wyswietlic dane w listy?

Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

Jak sprytnie użyjesz extend zamiast append to powinno pyknąć


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
SK
  • Rejestracja:ponad 13 lat
  • Ostatnio:ponad 7 lat
  • Postów:80
0

O cos takiego chodzilo? Jest juz lepiej, ale nadal mam liste z fragmentami wyrazow...

Kopiuj
    for slowo in zbior_slow:
        if wyraz.find(slowo) == 0:
            podzialy.append(slowo)
            if wyraz[len(slowo):] <> '':
                podzialy.extend( podzial_na_slowa( zbior_slow, wyraz[len(slowo):]) )
Guaz
  • Rejestracja:około 8 lat
  • Ostatnio:ponad 4 lata
  • Lokalizacja:Częstochowa
  • Postów:221
0
skolukmar napisał(a):

O cos takiego chodzilo? Jest juz lepiej, ale nadal mam liste z fragmentami wyrazow...

Zakładam że jest to spowodowane tym że część słów jest fragmentami innych.
Można to wyeliminować w prosty sposób, ale raczej on cię nie usatysfakcjonuje bo zapewne będzie wolniejszy, ponadto krótkie słowa nadal będą go psuć. Chyba że zdecydujemy się na wybieranie najdłuższych słów, to jednak wyeliminuje zwroty takie jak 'matematykę' gdy będziemy chcieli mieć faktycznie te słowa rozdzielone np: 'ten zbiór ma tematykę'...
Wiele by rozwiązało gdybyśmy wiedzieli ile ma być słów i podali to programowi, jednak zakładam że program sam ma rozwiązać ten problem :).

Kopiuj
zbior_slow = set()
start = 0
string = 'matematykapustkinieznosi'
temp = list()
for slowo in set_rzecz:
    if slowo in string[start:] and string[start:].startswitch(slowo):
        temp, start += [slowo], len(slowo)
#zbior_slow = ['ma','tematyka', 'pustki', 'nie', 'znosi']
for i in range(len(temp)-1):
    if temp[i] + temp[i+1] in set_rzecz:
        temp[i] += temp[i+1]
        del temp[i+1]
#zbior_slow = ['matematyka', 'pustki', 'nie', 'znosi'] 
#lub 'nieznosi' jeśli występowałoby w zbiorze słów. Zakładam że nie występuje jako niepoprawne.
            

Tak mi się wydaje :). Nie testowałem :p. Ale może cię to w jakiś sposób natchnie :).
W taki sposób gdybyś w dwóch miejscach eksportował temp'a do swojego zbioru, będziesz miał więcej poprawnych kombinacji - przynajmniej tak zakładam :).
Oczywiście nie jest to zoptymalizowane w żaden sposób, jeśli chcesz tego używać, to warto o tym pomyśleć. Da się to fajnie na kilka sposobów przyspieszyć, zakładam że nawet czterokrotnie, zależy jak szeroki jest słownik z którego dopasowuje słowa ;p.

PS: Są tu dwa błędy które pozostawiam tobie do rozwiązania, dla tego przykładu, może znaleźć słowo 'temat' przed 'tematyka' jeśli ten pierwszy będzie wcześniej wewnątrz zbioru.
Przez co nigdy nie znajdzie słowa zaczynającego się od 'yka'.
Drugi błąd, to taki że jeśli przejdzie przez słowo które występuje dalej w zbiorze, pominie je. Zamiast przypisać, przez co nie będzie występować, przykładowo, niech najpierw pod słowo podstawi 'nie' a później 'matematyka', później 'pustka', a później będzie szukać w nieskończoność 'nieznosi'. Czego oczywiście nie znajdzie.
Oba błędy idzie rozwiązać dzięki funkcji while start < len(string): która po przejściu przez cały zbiór słów, jeśli zgromadzi podzielony cały string, to spokojnie się zakończy, w innym wypadku powinno wyeliminować ostatnie znalezione słowo w temp'ie ze zbioru przyrównywanych.
Jakbyś miał problemy z dokończeniem programu, chętnie pomogę :)


Linux Mint
Arduino / Python 3.5.2
edytowany 4x, ostatnio: Guaz

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.