Prijavi problem


Obeleži sve kategorije koje odgovaraju problemu

Još detalja - opišite nam problem


Uspešno ste prijavili problem!
Status problema i sve dodatne informacije možete pratiti klikom na link.
Nažalost nismo trenutno u mogućnosti da obradimo vaš zahtev.
Molimo vas da pokušate kasnije.

Analiza i prezentacija podataka u Džupiteru

3. Низови симбола (стрингови или ниске)

У овој глави ћемо

  1. упознати стрингове као низове карактера
  2. видети како се приступа елементима стринга и како се издвајају делови стринга, и
  3. упознати основне операције са стринговима.

3.1. Стрингови (ниске)

Иако су настали као машине за обраду нумеричких података рачунари су доживели врхунас свог успеха када се схватило да они могу да обрађују и симболичке податке. Обрада симболичких података данас представља доминантан начин употребе рачунара.

Стринг је реч кнјижевног енглеског језика (енгл. string) чије основно значење је "објекти исте врсте нанизани на нит". Зато се стрингови често на српском зову и ниске. У Пајтону стринг је низ симбола. На пример, ово су стрингови:

"Zdravo! Kako si?"
'Основна школа "Јован Јовановић-Змај"'
":-)"
''
""

Видимо да се стрингови пишу тако што се између апострофа или наводника (свеједно је) наведе произвољан низ симбола. Последња два примера нам показују како изгледа празан стринг, односно, стринг који нема ниједно слово. Други пример нам показује како да се снађемо ако стринг треба да садржи наводнике: просто га оградимо апострофима.

Број симбола у стрингу се зове дужина стринга. Дужине стрингова из претходног примера су, редом, 16, 36, 3, 0 и 0.

Стрингове додељујемо променљивим као што смо и навикли, исписујемо их командом print, а учитавамо командом input. Команда input сачека да корисник унесе низ симбола и да на крају притисне [ENTER]. Она потом врати све симболе које је корисник унео као један низ симбола (такорећи стринг). На пример:

In [7]:
print("Unesi svoje ime, prvo u nominativu pa onda u vokativu")
ime = input("nominativ: ")
ime_v = input("vokativ: ")
print("Aha! Znao sam!")
print("Ti se zoveš", ime)
print("Zdravo,", ime_v)
Unesi svoje ime, prvo u nominativu pa onda u vokativu
nominativ: Dejan
vokativ: Dejane
Aha! Znao sam!
Ti se zoveš Dejan
Zdravo, Dejane

Уграђена функција len враћа дужину стринга и користи се овако:

In [6]:
print("Ti se zoveš", ime, "i tvoje ime ima", len(ime), "slova")
Ti se zoveš Dejan i tvoje ime ima 5 slova

Пример. Написати Пајтон програм који утврђује колико пута се неки симбол јавља у унетом стрингу.

In [9]:
print("Utvrdjujemo koliko puta se neki simbol javlja u unetom stringu")
c = input("Unesi simbol: ")
s = input("Unesi string: ")
broj = 0
for x in s:
    if x == c:
        broj += 1
print("Simbol", c, "se u unetom stringu javlja", broj, "puta")
Utvrdjujemo koliko puta se neki simbol javlja u unetom stringu
Unesi simbol: a
Unesi string: Blago vama, blago nama, blago svima sa mamama
Simbol a se u unetom stringu javlja 12 puta

Конструкција for x in s прође кроз цео стринг s слово по слово, па за свако појављивање симбола c увећамо бројач за 1.

Пример. Написати Пајтон програм који утврђује да ли је у датом стрингу број отворених заграда ( једнак броју затворених заграда ).

In [22]:
s = input("Unesi string: ")
br_otvorenih = 0
br_zatvorenih = 0
for x in s:
    if x == "(": br_otvorenih += 1
    if x == ")": br_zatvorenih += 1
if br_otvorenih == br_zatvorenih:
    print("isti je broj otvorenih i zatvorenih zagrada")
else:
    print("nije isti broj otvorenih i zatvorenih zagrada")
Unesi string: (a+b)*(s - t) = )(
isti je broj otvorenih i zatvorenih zagrada

3.2. Приступање елементима стринга и деловима стринга

Пошто је стринг низ симбола могуће је приступити појединачним симболима у стрингу, али и деловима стринга.

Indeksiranje stringa

Стринг је, дакле, низ кућица. У сваку кућицу је уписан таћно један симбол и свака кућица има кућни број. Као и раније, кућни бројеви крећу од нуле. На пример, ако ставимо

In [1]:
s = "Popokatepetl"

онда је

In [2]:
s[4]
Out[2]:
'k'

док је

In [3]:
s[0]
Out[3]:
'P'

Инересантно је (а касније ћемо видети да је и корисно!) то што низови у Пајтону имају и негативне коефицијенте. Последња кућица у низу има индекс -1 ("први од краја"), претпоследња -2 ("други од краја") и тако даље. Зато је:

In [4]:
s[-1]
Out[4]:
'l'
In [5]:
s[-5]
Out[5]:
'e'

Из стринга можемо лако да издвојимо његове делове употребом конструкције: $$ \mathtt{s[} m : n \mathtt{]} $$ која издваја део стринга који почиње од кућице са редним бројем $m$ и завршава се са кућицом чији редни број је $n - 1$ (обрати пажњу: не иде до $n$, већ до кућице пре). На ово ћемо морати мало да се привикнемо. На пример,

In [6]:
s[2:5]
Out[6]:
'pok'

Дакле, из стринга s смо издвојили симболе s[2], s[3] и s[4], односно, кренули смо од кућице број 2 и завршили непосредно пре 5. кућице.

Ако желимо да издвојимо део стринга који креће од 6. кућице и иде до краја стринга, написаћемо

In [7]:
s[6:]
Out[7]:
'tepetl'

С друге стране, ако желимо да издвојимо део стринга који креће од пошетка стринга и иде до 6. кућице (укљућујући и њу) написаћемо:

In [8]:
s[:7]
Out[8]:
'Popokat'

Не смемо заборавити да се кућица чији кућни број је наведен иза двотачке не укључује у сегмент!

Издвајање делова стринга у комбинацији са негативним индексима нам омогућује да концизно запишемо веома корисне конструкције. Рецимо, последња четири елемента стринга добијамо овако:

In [9]:
s[-4:]
Out[9]:
'petl'

што је концизан запис за део стринга "од -4. кућице па до краја". С друге стране, "све осим последња два" можемо да запишемо овако:

In [10]:
s[:-2]
Out[10]:
'Popokatepe'

Пример. Написати Пајтон функцију prebroj_podstr(p, s) која утврђује колико пута се стринг p јавља као подстринг стринга s.

In [15]:
def prebroj_podstr(p, s):
    broj = 0
    n = len(p)
    for i in range(len(s) - n + 1):
        if p == s[i:i+n]:
            broj += 1
    return broj

Да погледамо како функција ради:

In [18]:
prebroj_podstr("bana", "oprobana torta od banana")
Out[18]:
2

Пример. У сваком рачунарском систему се подаци пакују у фајлове (или датотеке) и од самих почетака рачунарске ере постоји обичај да се име фајла организује тако да последњих неколико симбола у имену фајла означава тип података који је у том фајлу похрањен. Тај део имена фајла се обично одвоји тачком од остатка имена фајла и зове се екстензија. Рецимо:

Екстензија Тип података
.txt текстуална датотека
.log текстуална датотека
.png слика
.jpg слика
.bmp слика
.mpg видео
.mp3 звук

Написати Пајтон програм који од корисника учитава име фајлса и на основу горње табеле одређује тип података који је података који је у њему похрањен. У случају да се екстензија имена фајла не налази у овој табели програм треба да пријави да се ради о непознатом типу података.

In [9]:
fajl = input("Unesi ime fajla: ")
ekstenzija = fajl[-4:] # uzimamo poslednja 4 simbola imena
if ekstenzija in [".txt", ".log"]:
    print("tekstualni fajl")
elif ekstenzija in [".png", ".jpg", ".bmp"]:
    print("slika")
elif ekstenzija == ".mpg":
    print("video")
elif ekstenzija == ".mp3":
    print("zvuk")
else:
    print("Ovaj format mi nije poznat")
Unesi ime fajla: /usr/dm/more.jpg
slika

Пример. Написати Пајтон функцију broj_reci(s) која у датом стрингу броји речи. Реч је непрекидан низ слова.

In [1]:
def broj_reci(s):
    n = len(s)
    broj = 0
    for i in range(n-1):
        if s[i].isalpha() and not s[i+1].isalpha():
            broj += 1
    if s[n-1].isalpha():
        broj += 1
    return broj

Напоменимо пре свега да уграђена функција isalpha() проверава да ли је нешто слово ("припадник неког алфабета").

Функција broj_reci(s) се ослања на једноставну идеју: када са слова пређемо на симбол који није слово, то је сигуран знак да смо управо детектовали једну реч и онда бројач увећавамо за 1. Ова стратегија ради за све речи у стрингу осим за последњу јер нам у том случају недостаје слово које је "окидач" за детектовање краја речи. Зато последња if наредба проверава да ли је последњи симбол у стрингу слово, како би и последња реч била урачуната.

Ево неколико примера:

In [2]:
broj_reci("Ovo je samo primer")
Out[2]:
4
In [3]:
broj_reci("Proba")
Out[3]:
1
In [4]:
broj_reci("!!!!")
Out[4]:
0

3.3. Операције са стринговима

У Пајтону, као и у већини модерних програмских језика, стрингови су непроменљиви (то својство се на енглеском зове immutability). На пример, нека је

In [10]:
s = "Banana"

Ако покушамо да променимо прво слово стринга на мало слово b добићемо грешку:

In [11]:
s[0] = "b"
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-11-b2ef3826bbc7> in <module>
----> 1 s[0] = "b"

TypeError: 'str' object does not support item assignment

Зато трансформације са стринговима увек своде на то да се од старог стринга изгради нови стринг који има својства која желимо. Једна од основних операција коју при томе користимо је надовезивање стрингова или конкатенација. Операција надовезивања стрингова се означава знаком +. На пример:

In [12]:
s = "Novi"
t = "Beograd"
s + t
Out[12]:
'NoviBeograd'

Важно је напоменути да надовезивање стрингова ради на најједноставнији могући начин: просто дода један стринг на крај оног другог, без уметања празнина или неке друге врсте мудровања.

Користећи операцију надовезивања можемо стрингу додати неки други стринг на почетак или на крај. На пример:

In [13]:
s = "bana"
s = "opro" + s
s
Out[13]:
'oprobana'
In [15]:
s = "bana"
s = s + "na"
s
Out[15]:
'banana'

Још једна интересантна операција је множење стринга бројем. На пример,

In [24]:
"Mir! " * 3
Out[24]:
'Mir! Mir! Mir! '

Пример. Исписати (за казну :-)) 100 пута: "Ученици не смеју да се гађају кредом!"

In [25]:
"Ученици не смеју да се гађају кредом!" * 100
Out[25]:
'Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!Ученици не смеју да се гађају кредом!'

Пример. Написати Пајтон функцију која обрће стринг.

In [16]:
def obrni_string(s):
    novi = ""
    for x in s:
        novi = x + novi
    return novi

Ова функција од стринга s у променљивој novi изгради нови стринг који садржи иста слова као и стринг s, али у обрнутом редоследу. На почетку поставимо стринг novi на празан стринг. Потом у циклусу слова стринга s додајемо на стринг novi, али једно по једно на почетак стринга novi. Тако прво слово стринга s постаје последње слово стринга novi, док последње слово стринга s на крају буде прво слово стринга novi. Другим речима, у стрингу novi изградимо слово по слово обрнуту верзију стринга s.

Погледајмо на пар примера како ова функција ради:

In [17]:
obrni_string("Proba")
Out[17]:
'aborP'
In [18]:
obrni_string("ana voli milovana")
Out[18]:
'anavolim ilov ana'

Пример. Написати Пајтон програм који проверава да ли је дата реченица палиндром. Приликом провере треба игнорисати празинине и величину слова. На пример, следеће реченице су палиндроми:

Ана воли Милована!
Сир има мирис?
Сава зидар ради за вас
Маја са Недом оде на сајам.

Решење. У решењу овог примера ћемо користити уграђену функцију isaplha() која проверава да ли је нешто слово, као и уграђену функцију lower() која од стринга прави нови у коме су сва слова мала.

In [21]:
s = input("Unesi string: ")
novi = ""
obrnut = ""
for x in s.lower():
    if x.isalpha():
        novi = novi + x
        obrnut = x + obrnut
if novi == obrnut:
    print("jeste palindrom")
else:
    print("nije palindrom")
Unesi string: Sir ima miris!
jeste palindrom

3.4. Задаци

Задатак 1. Написати Пајтон програм који од корисника учитава стринг и онда утврђује број самогласника и број сугласника у том стрингу.

In [ ]:
 

Задатак 2. Написати Пајтон функцију poslednja_rec(s) која из датог стринга издваја последњу реч која је наведена у стрингу. Ако у стрингу не постоји ниједно слово функција треба да врати празан стринг. (Напомена: реч је непрекидан низ слова.)

In [ ]:
 

Задатак 3. Написати пајтон функцију ispravi_interpunkciju(s) која у датом стрингу додаје по једну празнину иза сваког знака интерпункције, али само ако је то потребно. На пример, за стринг

"Halo?Da? Ne.Ko je to?"

функција треба да врати:

"Halo? Da? Ne. Ko je to?"
In [ ]:
 

Задатак 4. Написати Пајтон функцију obrni_reci(s) која од датог стринга прави нови у коме су речи послагане од последње према првој. На пример, за стринг

"Napisati program koji ispisuje reci unetog teksta u obrnutom poretku"

функција треба да врати:

"poretku obrnutom u teksta unetog reci ispisuje koji program Napisati"
In [ ]:
 

Задатак 5*. Написати Пајтон функцију која проверава да ли су у датом стрингу заграде ( и ) балансиране. То значи да у стрингу имамо исти број отворених и затоврених заграда, и да не постоји почетни сегмент стринга у коме је број затворених заграда већи од броја отворених.

In [ ]:
 

Задатак 6. Написати Пајтон функцију razmeni(s, din_za_1_eur) која конвертује дати износ из динара у евре и обрнуто. Стринг s садржи износ записан у облику $\langle \mathrm{broj} \rangle \langle \mathrm{valuta} \rangle$, на пример овако:

125 DIN
217.50 EUR
1527.99 DIN
50 EUR

док аргумент din_za_1_eur представља вредност једног евра у динарима. Функција треба да врати стринг који има облик $\langle \mathrm{broj} \rangle \langle \mathrm{valuta} \rangle$. При томе ти могу од користи бити уграђене функције float и str. За неки стринг p функција float(p) враћа број који је записан стрингом p игноришући при том празнине које се можда јављају у стрингу. На пример:

In [ ]:
 
In [28]:
float("  123.4 ")
Out[28]:
123.4

С друге стране, функција str од неког броја прави стринг који садржи његов запис. На пример:

In [29]:
str(2.89)
Out[29]:
'2.89'

Функција razmeni треба да ради овако:

razmeni("124.99 EUR", 117.90)
'14736.321‬ DIN'

razmeni("12000 DIN", 117.90)
'‭101.7811704 EUR'
In [ ]: