Napisy (łańcuchy znakowe)

  • napisy to ciąg znaków umieszczony między 'apostrofami'
  • napis w Matlab to wektor znaków
  • macierz znakowa - macierz zawierająca napisy w wierszach, wiersze macierzy posiadają tyle samo elementów, więc krótsze napisy są wypełnione blankami/spacjami
  • od Matlab R2016 istnieje także obiekt (typ) string, który reprezentuje napisy umieszczone w "cudzysłowach" (ale my zajmiemy się tylko tablicami znaków)
napis = 'Ala ma kota'
a = length(napis)
whos napis 
napis = Ala ma kota
a =  11
Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  ===== 
        napis       1x11                        11  char

Total is 11 elements using 11 bytes
c = length('')     % pusty napis
b = length(' ')    % znak spacji
c = 0
b =  1
  • indeksowanie macierzowe
  • operacje na macierzach (np. transpozycja)
napis = 'Ala ma kota';
a = napis(1)
b = napis(end)
c = napis(2:2:end)
d = napis(1:5)'
a = A
b = a
c = l akt
d =

A
l
a
 
m

Ćwiczenie napisz funkcję anagram(s), która dla podanego napisu (wyrazu) zwróci jego anagram (przestawi znaki w losowej kolejności).
Wskazówka: funkcja randperm() zwraca losową permutację liczb całkowitych

  • macierz zawierająca napis (tablicę znaków) w każdym wierszu
  • długość wierszy musi być taka sama
X = [ 'Ala' ; 'Ewa'; 'Jan'] 

% piwrsza kolumna znaków
a = X(:, 1) 

% transpozycja macierzy
b = X'
X =

Ala
Ewa
Jan

a =

A
E
J

b =

AEJ
lwa
aan

Funkcja char(s1, s2, ...) tworzy macierz z napisów s1, s2, itd.

X = [ 'Ala' ; 'Zuzanna']  

whos
% uwaga: w Matlab ta operacja powoduje błąd, nie zgadzają się długości napisów. W Octave pierwszy wiersz jest uzupełniony spacjami
% Do tworzenia macierzy znakowej można wykorzystać char(), który uzupełni krótsze linie spacjami

X = char('Ala', 'Zuzanna', 'Hermenegilda')
X =

Ala    
Zuzanna

Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  ===== 
        X           2x7                         14  char
        a           3x1                          3  char
        ans         1x5                          5  char
        b           3x3                          9  char
        c           1x5                          5  char
        d           5x1                          5  char
        napis       1x11                        11  char

Total is 52 elements using 52 bytes

X =

Ala         
Zuzanna     
Hermenegilda
  • łączenie napisów (concatenation) [napis1 napis2]
  • funkcja strcat(napis1, napis2)
a = 'Ala';
b = ' ma kota';
x = [a b]
y = [x ' a Ewa ma psa']
x = Ala ma kota
y = Ala ma kota a Ewa ma psa
z = strcat(a, b, ' a Janek nie')
whos a b c
z = Ala ma kota a Janek nie
Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  ===== 
        a           1x3                          3  char
        b           1x8                          8  char
        c           1x5                          5  char

Total is 16 elements using 16 bytes
  • łaczenie napisów wertykalne (dodawanie wierszy) [napis1 ; napis2]
  • funkcja strvcat(napis1, napis2)
a = 'Raz';
b = 'Dwa';
c = 'Trzy'; 

% w Matlab problem bo wiersze o różnej długości
x = [a ; b; c]     
x =

Raz 
Dwa 
Trzy
% w Matlab działa, krótsze wiersze zostają uzupełnione spacjami 
y = strvcat(a, b, c)

whos a b c x y
y =

Raz 
Dwa 
Trzy

Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  ===== 
        a           1x3                          3  char
        b           1x3                          3  char
        c           1x4                          4  char
        x           3x4                         12  char
        y           3x4                         12  char

Total is 34 elements using 34 bytes
  • znaki są kodowane za pomocą liczb całkowitych (kod ASCII)
  • char(liczba) zwraca symbol kodowany daną liczbą
  • double(znak) zwraca liczbę kodującą znak
a = char(65)
b = double('A')
a = A
b =  65
napis = 'Ala ma kota'
b = double(napis)
b = napis + 1
c = char(napis + 3)
napis = Ala ma kota
b =

    65   108    97    32   109    97    32   107   111   116    97

b =

    66   109    98    33   110    98    33   108   112   117    98

c = Dod#pd#nrwd

Ćwiczenie: wypisz wartości numeryczne i odpowiadające symbole kodu ASCII dla znaków kodowanych od 1 do 127

  • char(10)
  • newline (brak w Octave)
  • sprintf('\n')
  • uwaga: w Windows na końcu linii są 2 bajty \r\n
x = ['Ala ' newline 'ma' char(10) 'kota']
warning: the 'newline' function is not yet implemented in Octave

Please read <https://www.octave.org/missing.html> to learn how you can
contribute missing functionality.
error: 'newline' undefined near line 1 column 14

Ćwiczenie: wyświetl wartość liczbową kodu ASCII odpowiadającą znakowi powrotu karetki \r

Funkcja Opis
strcat() strvcat() łączenie napisów
blanks(N) tworzy napis (wektor) białych znaków (spacji)
sprintf() tworzenie napisów z formatowanymi wartościami
strcmp(A, B) porównywanie napisów
strtrim(x) usuwa białe znaki z poczatku i z końca napisu
lower(x) zamiana znaków na małe litery
upper(x) zamiana znaków na wielkie litery
findstr(s1, s2) szuka wzorca s2 w napisie s1
strrep(s, w, x) zamiana w napisie s wystąpienia wzorca w na x
strtok(s, d) dzieli napis s na części oddzielone separatorem d

W Matlab zobacz help strfun

a = blanks(10)
x = double(a)
a =           
x =

   32   32   32   32   32   32   32   32   32   32
b = ['Ala' blanks(5) 'ma' blanks(5) 'kota']
c = ['Ala' ; blanks(5)' ; 'ma' blanks(5) 'kota']

% w Matlab raczej to
c = char('Ala', blanks(5)','ma',blanks(5), 'kota')
b = Ala     ma     kota
c =

Ala        
           
           
           
           
           
ma     kota

c =

Ala  
     
     
     
     
     
ma   
     
kota 

działa identycznie jak fprintf ale wynikowy napis jest zwracany (nie wyświetlany)

a = sprintf('Liczba PI wynosi %.2f', pi )
x = 65
b = sprintf('Liczba %d, znak %c\n\nliczba %x\n', x, x, x)
a = Liczba PI wynosi 3.14
x =  65
b = Liczba 65, znak A

liczba 41
% sprintf z macierzami w argumentach
x = [1 2 3]
a = sprintf('Liczba %d, ', x)
a = sprintf('Liczba %d, ', x')
x = [1 2 ; 3 4]
a = sprintf('Liczba %d, ', x)
x =

   1   2   3

a = Liczba 1, Liczba 2, Liczba 3, 
a = Liczba 1, Liczba 2, Liczba 3, 
x =

   1   2
   3   4

a = Liczba 1, Liczba 3, Liczba 2, Liczba 4, 

usuwa białe znaki z początku i końca napisu

X = [ blanks(5) 'matlab' blanks(5) 'jest fajny' blanks(5)]
a = strtrim(X)
X =      matlab     jest fajny     
a = matlab     jest fajny
X = 'Ala ma KoTa 123!@#'
a = lower(X)
b = upper(X)
X = Ala ma KoTa 123!@#
a = ala ma kota 123!@#
b = ALA MA KOTA 123!@#

Ćwiczcie zamień w napisie duże litery na małe bez używania funkcji lower ?

  • funkcja strcmp(S1, S2) zwraca 1 gdy napisy s1 i s2 są identyczne
  • funkcja strcmpi(S1, S2) zwraca 1 gdy napisy s1 i s2 różnią sie wyłącznie wielkością liter
x = 'abcd'
y = 'abcD'

a = x == y 
b = x < y    % porównywanie wartości liczbowych w macierzach

c = strcmp(x, y)

d = strcmpi(x, y)
x = abcd
y = abcD
a =

  1  1  1  0

b =

  0  0  0  0

c = 0
d = 1
  • funkcja strfind(s, w) zwraca indeksy początku wzorca w w napisie s
napis = 'Siała baba mak'

a = strfind(napis, 'abc')
b = strfind(napis, 'mak')
c = strfind(napis, 'a')
napis(c)
napis = Siała baba mak
a = [](0x0)
b =  13
c =

    3    6    9   11   14

ans = aaaaa
  • funkcja strrep(s, w, x) zamienia w napisie s wystąpienia wzorca w na napis x
napis = 'siała baba mak'
napis = strrep(napis, 'baba', 'kobieta')
napis = siała baba mak
napis = siała kobieta mak
  • funkcja strtok(s, d) dzieli napis s na część przed separatorem (token) d oraz część pozostałą. Domyślnie separatorem jest spacja.
napis = 'siała baba mak'
[token reszta] = strtok(napis)

[token reszta] = strtok(napis, 'a')

[token reszta] = strtok(napis, 'baba')
napis = siała baba mak
token = siała
reszta =  baba mak
token = si
reszta = ała baba mak
token = si
reszta = ała baba mak
Funkcja Opis
isletter(s) czy litera
isspace(s) czy spacja
islower(s) czy mała litera alfabetu
isupper(s) czy duża litera alfabetu
isdigit(s) czy cyfra
ischar(s) czy napis
napis = 'abc ABC 123\n!@#'
a = isletter(napis)
b = isspace(napis)
c = islower(napis)
d = isupper(napis)
e = isdigit(napis)
e = ischar(napis)
f = ischar([ 1 2 3])
napis = abc ABC 123\n!@#
a =

  1  1  1  0  1  1  1  0  0  0  0  0  1  0  0  0

b =

  0  0  0  1  0  0  0  1  0  0  0  0  0  0  0  0

c =

  1  1  1  0  0  0  0  0  0  0  0  0  1  0  0  0

d =

  0  0  0  0  1  1  1  0  0  0  0  0  0  0  0  0

e =

  0  0  0  0  0  0  0  0  1  1  1  0  0  0  0  0

e = 1
f = 0
Funkcja Opis
int2str(x) zamiana liczby całkowitej na napis
num2str(x) zamiana liczby na napis
sprintf() również pozwala na zmiane liczby na napis
str2num(s) zamiana napisu na liczbę
a = int2str(65)
double(a)     % 54 to cyfra '6', wartość 53 to cyfra '5'
printf('%s\n', a)
a = 65
ans =

   54   53

65
b = num2str(pi)
b(1:2)
b = 3.1416
ans = 3.
c = str2num(b)
d = str2num('1 2 3.5')
whos a b c d
c =  3.1416
d =

   1.0000   2.0000   3.5000

Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  ===== 
        a           1x2                          2  char
        b           1x6                          6  char
        c           1x1                          8  double
        d           1x3                         24  double

Total is 12 elements using 40 bytes
  • funkcja sort() zwraca znaki w rosnącej kolejności
x = 'Ala ma kota'
sort(x)

x = ['Ala' ; 'ma ' ; 'psa']
sort(x, 2)
x = Ala ma kota
ans =   Aaaaklmot
x =

Ala
ma 
psa

ans =

Aal
 am
aps

Napisz funkcję o nazwe dekoduj(), która odszyfruje wiadomość ukrytą w pierwszych literach wyrazów podanego napisu. Dla podanego w argumencie funkcji łańcucha znakowego zawierającego dowolnie długi tekst funkcja zwraca łancuch znakowy zawierający litery początkowe wyrazów. Wynik zawiera wyłacznie małe litery, jeżeli pierwsza litera wejściowego wyrazu była duża to zamieniamy ją na małą. Wyrazem jest dowolny ciąg składający się z liter (dużych lub małych) lub cyfr. Zwróć uwagę na to, że tekst może zawierać wiele innych znaków z kodu ASCII (np. #$\_), które mogą oddzielać wyrazy (ciągi liter i cyfr). W przypadku, gdy użytkownik wywoła funkcję bez podania argumentu wejściowego lub poda więcej argumentów niż 1 wówczas funkcja wyświetli stosowany komunikat błędu za pomocą funkcji error(). Komunikat błedu pojawi się również, gdy podany argument nie będzie tablicą znakową.

Przykładowo, wywołanie funkcji

dekoduj('Ala ma kota');

zwróci napis 'amk'

Inny przykład, dla danej tablicy x

x = '  **mbnv,AaA[(T)]     l123|A||B  '

wywołanie funkcji dekoduj(x) zwróci napis 'matlab'