Vezano za zadatak 41 - koristis previse promenljivih koje ne sluze nicemu i tesko mozes da pohvatas gde je sta. Potrebna ti je samo jedna lista, koju dobijas split() funkcijom, sto si vec lepo uradio. Nazovimo je rows (to je ovo sto ti zoves 'novi'). Takodje, ja bih dodao i funkciju lower(), kojom eliminises mala/velika slova (tekst zadatka kaze "case is not important"):
Code (python):rows = text.replace(' ', '').split('\n').lower()
Ta lista vec sadrzi linije teksta, koje su obicni stringovi, unutar kojih rec definisanu promenljivom word trazis funkcijom find(). Funkcija find() vraca poziciju stirnga unutar veceg stringa, pa imas:
Code (python):
>>> verse = 'The woods are lovely, dark and deep'
>>> verse.find('wood')
4
>>> verse.find('forest')
-1
Time resavas skeniranje teksta po horizontali. Ostaje da resis skeniranje po vertikali, sto nije toliko slozeno, imajuci u vidu da svakom slovu unutar stringa mozes da pridjes po njegovom indeksu. Na primer, ako ti rows sadrzi:
Code (python):rows = [ 'thewoodsarelovely,darkanddeep', 'butihavepromisestokeep,', 'andmilestogobeforeisleep,' 'andmilestogobeforeisleep.' ]
Tada ti je rows[0][1] == 'h' (drugo slovo prvog reda). Znaci, nisu ti potrebni nikakvi indeksi. Jedini problem je sto su elementi liste nejednake duzine, tako da najpre moras da odredis najvecu duzinu elementa liste koja ce ti odrediti opseg skeniranja. Dobijas kod u formi:
Code (python):
def checkio (text, word):
rows = text.replace(' ', '').split('\n') # Smesta linije teksta u listu rows
# Najpre odredimo maksimalnu duzinu linije
max_len = 0
for row in rows:
if (len(row)>max_len):
max_len = len(row)
# Iteracija po vertikali, slovo po slovo svakog reda, do maksimalne duzine reda
for j in range(0,max_len):
col = '' # Ovde smestamo kolone teksta
for i,row in enumerate(rows):
if (j >= len(row)):
continue
col += row[j] # Slovo na poziciji 'j' unutar stringa 'row'
# col - ce sadrzati celu kolonu teksta
Ostaje ti da nadjes poziciju reci u stringovima
row i
col. Tu imas dve ideje. Onako skolski, pocetnicki bi bilo da kolone smestas u posebnu listu (npr.
cols), koju inicijalizujes na pocetku i kada formiras kolonu (
col) na kraju ovog koda gore dodas:
Code (python):
if (col):
cols.append(col)
U nastavku koda onda ponovo iteriras po svim vrstama i svim kolonama i koristis funkciju find(). To je korektno resenje, ali time nepotrebno ponovo ulazis u petlju. Da ustedis vreme, pretrazivanje stringova mozes da radis vec i u petljama gore. Prva petlja iterira po kolonama, druga za svaku kolonu skenira vrste od 0 do len(rows). U principu, dovoljno je ispitati vrste samo jednom i idealno je to uraditi tokom skeniranja prve kolone. Slicno tome, skeniranje kolone je najbolje uraditi kada se kolona formira. Time kod postaje (nisam testirao, ali mislim da je ok):
Code (python):
def checkio (text, word):
rows = text.replace(' ', '').split('\n') # Smesta linije teksta u listu rows
# Najpre odredimo maksimalnu duzinu linije
max_len = 0
for row in rows:
if (len(row)>m):
max_len = len(row)
# Iteracija po vertikali, slovo po slovo svakog reda
for j in range(0,max_len):
col = '' # Ovde smestamo kolone teksta
for i,row in enumerate(rows):
if (j == 0): # Tokom formiranja prve kolone skeniramo vrstu
pos = row.find(word)
if (pos >= 0):
return [ i, pos, i, pos+len(word)-1 ]
if (j >= len(row)):
continue
col += row[j]
pos = col.find(word)
if (pos >= 0):
return [ pos, j, pos+len(word)-1, j ]
return []
Moze li to bolje? Moze! Recimo, ako se rec ne nalazi uopste u tekstu zasto bismo je trazili u svakom redu? Na samom pocetku funkcije treba onda dodati:
Code (python):def checkio (text, word):
search_rows = word in text
I onda u liniji gde ispitujemo da li je j == 0 izmeniti:
Code (python):
if ((j == 0) and search_rows): # Tokom formiranja prve kolone skeniramo vrstu, samo ako je search_row == True
Zadatak moze da se malcice uopsti i da se traze sve koordinate gde se zadata rec nalazi ... i da se to vraca u formi:
[ [ x1, y1, z1, u1 ], [ x2, y2, z2, u2 ], ... ]
To ti ostavljam za domaci ...
[Ovu poruku je menjao B3R1 dana 18.05.2020. u 19:27 GMT+1]