Pyrhon - algorytm podzialu napisu na slowa

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.

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.

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

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

0

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

0

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

    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):]) )
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 :).

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ę :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1