Zadanie z matury 2018

0

Znajdź słowo, w którym występuje największa liczba różnych liter. Wypisz to słowo i liczbę
występujących w nim różnych liter. Jeśli słów o największej liczbie różnych liter jest więcej
niż jedno, wypisz pierwsze z nich pojawiające się w pliku z danymi.
Zrobilem takie cos i nie wiem co dalej:

slowo=open("sygnaly.txt")
slownik={}
for znak in slowo:
    slownik[znak]=0
print(len(slownik))
0
  1. W pliku są SŁOWA ODDZIELONE ZNAKIEM NOWEJ LINII, a nie jedno słowo :) (tu coś będzie o tym, jak to rozdzielić https://www.pythonforbeginners.com/dictionary/python-split)
  2. Potrzebujesz fora w forze.
for slowo in slowa:
        znaki_w_slowie = Set()
        for znak in list(slowo):
            znaki_w_slowie.add(znak)

Set zawiera tylko unikalne elementy, więc liczba unikalnych liter w słowie jest równa len(znaki_w_slowie)
Jeszcze kilka poprawek i gotowe :)

EDIT
W zasadzie to można tworzyć Set z list, więc równie dobrze można zrobić znaki_w_slowie = Set(list(slowo)) i drugi for nie jest potrzebny.

0

czyli do mojego kodu mam dopisać twój czy cały mój mam usunąć ?

0
result = {'word': '', 'unique_chars': 0}
with open('xd') as f:
    for line in f:
        word = line.strip().lower()
        unique_chars = len(set(word))
        if result['unique_chars'] < unique_chars: result = {'word': word, 'unique_chars': unique_chars}
print(f"{result['word']} {result['unique_chars']}")

Tłumaczenie tego co robimy:

  1. otwieramy plik f jako context - tak by nie musieć ręcznie robić .close()
  2. jako f otworzony nam został dany plik, oraz przekształcony w iterabla, po którym możemy iterować - iterowanie po nim spowoduje wczytywanie linijka po linijce - to robimy za pomocą pętli for
  3. jako word zapisujemy sobie daną linię (bo jedno słowo jest na linijkę) i usuwamy z niego białe znaki, znaki końca linii itd. metodą strip()
  4. potem tworzymy zmienną unique_chars, która będzie równa długości seta z danego słowa, set() to nic innego jak zbiór unikalnych elemntów z danego iterabla, a stringi w pythonie są iterowalne, więc nie musimy castować na listę czy coś innego
  5. jeśli długość obecnego słowa - unique_chars jest większa od długości zapisanej w rezultacie, to wtedy uaktualniamy rezultat. Dzięki temu, że mamy tu < a nie <= to rezultat zostanie pierwszym jesli póxniej napotkamy inne słowa z taką samą liczbą znaków.
    6, wyprintowujemy wynik

Można całość jeszcze skrócić jeśli nie dbmay o czytelność a tylko o LOC:

result = {'word': '', 'unique_chars': 0}
with open('xd') as f:
    for line in f:
           if  result['unique_chars'] < len(set(line.strip().lower())): result = {'word': line.strip().lower(), 'unique_chars': len(set(line.strip()))}

Edit - nie wiem, czy A i a są tutaj traktowane jako różne litery, ale jeśli tak, to trzeba wyrzucić .lower()

2

A dla leniwych (jak akurat lubią tracić mało czasu w trakcie matury), oto szybkie rozwiązanie:

with open("sygnaly.txt") as f:
    lines = f.read().splitlines()
    m = max(lines, key=lambda s: len(set(s)))
    print(m, len(set(m)))

Edit: wersja używająca mniej dodatkowej pamięci:

with open("sygnaly.txt") as f:
    m = max(f, key=lambda s: len(set(s)))
    print(m, len(set(m)))
0

Zaproponuje swoje rozwiązanie jakby ktoś dociekliwy robił test szybkości z jakimś dużym słownikiem :).

best = ("",0)
with open("sygnaly.txt") as f:
    for line in f:
        tmp_len = len(set(line))
        if tmp_len > best[1]:
            best = (line, tmp_len)
print(*best)

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