Łańcuchy znakowe. Martyna Stańczyk Katarzyna Więckiewicz. Płock, 17 kwietnia 2014

Podobne dokumenty
ALGORYTMY I STRUKTURY DANYCH

wagi cyfry pozycje

Zadanie 1. Zmiana systemów. Zadanie 2. Szyfr Cezara. Zadanie 3. Czy liczba jest doskonała. Zadanie 4. Rozkład liczby na czynniki pierwsze Zadanie 5.

1. Operacje logiczne A B A OR B

Luty 2001 Algorytmy (7) 2000/2001

ARYTMETYKA BINARNA. Dziesiątkowy system pozycyjny nie jest jedynym sposobem kodowania liczb z jakim mamy na co dzień do czynienia.

DZIAŁANIA NA UŁAMKACH DZIESIĘTNYCH.

Zadanie 1. Potęgi (14 pkt)

Problem W przedziale całkowitym <a,b> wyszukaj wszystkie liczby parzyste.

Algorytmy przeszukiwania wzorca

1. Podstawowe pojęcia dotyczące przetwarzania tekstów 2. Podstawowe operacje na łańcuchach znakowych 3. Naiwne wyszukiwanie wzorca w tekście 4.

B.B. 2. Sumowanie rozpoczynamy od ostatniej kolumny. Sumujemy cyfry w kolumnie zgodnie z podaną tabelką zapisując wynik pod kreską:

0 --> 5, 1 --> 7, 2 --> 9, 3 -->1, 4 --> 3, 5 --> 5, 6 --> 7, 7 --> 9, 8 --> 1, 9 --> 3.

1. Napisz program, który wyświetli Twoje dane jako napis Witaj, Imię Nazwisko. 2. Napisz program, który wyświetli wizytówkę postaci:

LABORATORIUM PROCESORY SYGNAŁOWE W AUTOMATYCE PRZEMYSŁOWEJ. Zasady arytmetyki stałoprzecinkowej oraz operacji arytmetycznych w formatach Q

Podstawy Informatyki

Zapis liczb binarnych ze znakiem

0 + 0 = 0, = 1, = 1, = 0.

Pracownia Komputerowa wykład V

Wstęp do Informatyki

2 Kryptografia: algorytmy symetryczne

INŻYNIERIA BEZPIECZEŃSTWA LABORATORIUM NR 2 ALGORYTM XOR ŁAMANIE ALGORYTMU XOR

EGZAMIN MATURALNY Z INFORMATYKI

CIĄGI wiadomości podstawowe

n, m : int; S, a, b : double. Gdy wartości sumy składowej nie można obliczyć, to przyjąć Sij = 1.03 Dla obliczenia Sij zdefiniować funkcję.

Rozwiązywanie układów równań liniowych metody dokładne Materiały pomocnicze do ćwiczeń z metod numerycznych

Arytmetyka liczb binarnych

Zaawansowane algorytmy i struktury danych

W. Guzicki Zadanie 41 z Informatora Maturalnego poziom podstawowy 1

2 Arytmetyka. d r 2 r + d r 1 2 r 1...d d 0 2 0,

Liczby rzeczywiste. Działania w zbiorze liczb rzeczywistych. Robert Malenkowski 1

Kod U2 Opracował: Andrzej Nowak

4. Postęp arytmetyczny i geometryczny. Wartość bezwzględna, potęgowanie i pierwiastkowanie liczb rzeczywistych.

Iteracje. Algorytm z iteracją to taki, w którym trzeba wielokrotnie powtarzać instrukcję, aby warunek został spełniony.

EGZAMIN MATURALNY Z INFORMATYKI MAJ 2010 POZIOM ROZSZERZONY CZĘŚĆ I WYBRANE: Czas pracy: 90 minut. Liczba punktów do uzyskania: 20 WPISUJE ZDAJĄCY

(mniejszych od 10 9 ) podanych przez użytkownika, wypisze komunikat TAK, jeśli są to liczby bliźniacze i NIE, w przeciwnym przypadku.

Teoria liczb. Magdalena Lemańska. Magdalena Lemańska,

Macierze. Rozdział Działania na macierzach

Cyfrowy zapis informacji

Arytmetyka komputera. Na podstawie podręcznika Urządzenia techniki komputerowej Tomasza Marciniuka. Opracował: Kamil Kowalski klasa III TI

Wykład 4. Określimy teraz pewną ważną klasę pierścieni.

Sortowanie przez wstawianie Insertion Sort

Dlaczego nie wystarczają liczby wymierne

Wykład 2. Informatyka Stosowana. 10 października Informatyka Stosowana Wykład 2 10 października / 42

Przykładowe zadania z teorii liczb

Programowanie 2 - Tablice i łańcuchy

Zadanie 4.3. (0 5) Błąd bezwzględny przybliżonej wartości liczby pi, wyznaczonej z n punktów, definiujemy następująco:

Wykład 2. Informatyka Stosowana. 9 października Informatyka Stosowana Wykład 2 9 października / 42

Podstawą w systemie dwójkowym jest liczba 2 a w systemie dziesiętnym liczba 10.

5. Rozwiązywanie układów równań liniowych

a) Zapisz wynik działania powyższego algorytmu dla słów ARKA i MOTOR...

Samodzielnie wykonaj następujące operacje: 13 / 2 = 30 / 5 = 73 / 15 = 15 / 23 = 13 % 2 = 30 % 5 = 73 % 15 = 15 % 23 =

PROBLEM. Znaleźć rozkład liczby p > 1. na iloczyn czynników pierwszych.

Relacje. opracował Maciej Grzesiak. 17 października 2011

Kryptografia systemy z kluczem tajnym. Kryptografia systemy z kluczem tajnym

Wprowadzenie do informatyki i użytkowania komputerów. Kodowanie informacji System komputerowy

Zadania do wykonania. Rozwiązując poniższe zadania użyj pętlę for.

II klasa informatyka rozszerzona SZYFROWANIE INFORMACJI

Matematyka dyskretna. Andrzej Łachwa, UJ, /10

Kod znak-moduł. Wartość liczby wynosi. Reprezentacja liczb w kodzie ZM w 8-bitowym formacie:

lekcja 8a Gry komputerowe MasterMind

Programowanie w Baltie klasa VII

WYRAŻENIA ALGEBRAICZNE

Pracownia Komputerowa wyk ad V

Sumy kwadratów kolejnych liczb naturalnych

Kurs ZDAJ MATURĘ Z MATEMATYKI MODUŁ 2 Teoria liczby rzeczywiste cz.2

1. Systemy liczbowe. addytywne systemy w których wartośd liczby jest sumą wartości jej znaków cyfrowych.

EGZAMIN MATURALNY Z INFORMATYKI MAJ 2010 POZIOM PODSTAWOWY CZĘŚĆ I WYBRANE: Czas pracy: 75 minut. Liczba punktów do uzyskania: 20 WPISUJE ZDAJĄCY

Czas pracy: 60 minut

Operacje arytmetyczne

Dla człowieka naturalnym sposobem liczenia jest korzystanie z systemu dziesiętnego, dla komputera natomiast korzystanie z zapisu dwójkowego

ALGORYTMY Algorytm poprawny jednoznaczny szczegółowy uniwersalny skończoność efektywność (sprawność) zmiennych liniowy warunkowy iteracyjny

Rozdział 5. Macierze. a 11 a a 1m a 21 a a 2m... a n1 a n2... a nm

Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego

SYSTEMY LICZBOWE 275,538 =

Ciała i wielomiany 1. przez 1, i nazywamy jedynką, zaś element odwrotny do a 0 względem działania oznaczamy przez a 1, i nazywamy odwrotnością a);

2. Układy równań liniowych

Zestaw 2 Organizacja plików: Oddajemy tylko źródła programów (pliki o rozszerzeniach.cpp)!!!

Wstęp do metod numerycznych Eliminacja Gaussa Równania macierzowe. P. F. Góra

INFORMATYKA Z MERMIDONEM. Programowanie. Moduł 5 / Notatki

1 Działania na zbiorach

12. Wprowadzenie Sygnały techniki cyfrowej Systemy liczbowe. Matematyka: Elektronika:

Liczby całkowite i rzeczywiste

Sortowanie. LABORKA Piotr Ciskowski

SYSTEMY LICZBOWE. Zapis w systemie dziesiętnym

Załóżmy, że musimy zapakować plecak na wycieczkę. Plecak ma pojemność S. Przedmioty mają objętości,,...,, których suma jest większa od S.

Jednym z najprostszych sposobów porządkowania jest technika stosowana przy sortowaniu listów:

Pzetestuj działanie pętli while i do...while na poniższym przykładzie:

Rozwiązaniem jest zbiór (, ] (5, )

Wykład 1. Na początku zajmować się będziemy zbiorem liczb całkowitych

Algorytmy i struktury danych. wykład 8

Lista 0. Kamil Matuszewski 1 marca 2016

Rozwiązywanie układów równań liniowych

Urządzenia Techniki. Klasa I TI. System dwójkowy (binarny) -> BIN. Przykład zamiany liczby dziesiętnej na binarną (DEC -> BIN):

do instrukcja while (wyrażenie);

Metody i analiza danych

WYKŁAD 3 (13 MARZEC 2014) LICZBY CAŁKOWITE I RZECZYWISTE. Bartosz Łakomy i Dariusz Dobiesz

Arytmetyka stałopozycyjna

Podstawowe operacje arytmetyczne i logiczne dla liczb binarnych

3. Macierze i Układy Równań Liniowych

Transkrypt:

Łańcuchy znakowe Martyna Stańczyk Katarzyna Więckiewicz Płock, 17 kwietnia 2014

Wyszukiwanie palindromów Przez palindrom (ang. palindrome) rozumiemy łańcuch znakowy s, który czyta się tak samo w obu kierunkach. Przykład: ABBCBBA jest palindromem ABBCABA nie jest palindromem Palindromy pojawiają się w genetyce (łańcuchy DNA, RNA), w tekstach, muzyce, matematyce, geometrii, fizyce itd. Stąd duże zainteresowanie informatyków w efektywnych algorytmach ich znajdowania. W badaniach genetycznych często szuka się tzw. przybliżonych palindromów (ang. aproximate palindromes), tzn. palindromów, w których do k-znaków może być błędnych, czyli nie pasujących do dokładnego palindromu (ang. exact palindrome). Takie palindromy występują w łańcuchach DNA, w których wystąpiły różnego rodzaju błędy genetyczne. Problemem palindromów przybliżonych nie zajmujemy się w tym opracowaniu.

Wyszukiwanie palindromów Wprowadźmy symbol s R, który oznacza łańcuch znakowy o odwróconej kolejności znaków w stosunku do łańcucha s. Przykład: s = ABCD s R = DCBA Łańcuch s jest palindromem, jeśli da się rozłożyć na dwa podłańcuchy w i w R wg poniższego schematu: s = ww R palindrom parzysty (ang. even palindrome), lub s = wxw R palindrom nieparzysty (ang. odd palindrome), gdzie X jest dowolnym symbolem alfabetu. Przykład: ABCDDCBA palindrom parzysty ABCD + DCBA ABCDADCBA palindrom nieparzysty ABCD + A + DCBA Zauważ, iż zgodnie z tą definicją palindromem jest każdy łańcuch pusty rozkłada się na dwa puste podłańcuchy oraz każdy łańcuch jednoliterowy rozkłada się na znak X i dwa puste podłańcuchy. Ponieważ są to przypadki trywialne, w poniższym zadaniu wprowadzono zastrzeżenie, iż wyszukiwane palindromy muszą być co najmniej dwuznakowe.

Wyszukiwanie palindromów Problem: W łańcuchu s znaleźć wszystkie palindromy o długości większej od 1. Rozwiązanie nr 1 Pierwszy algorytm wyszukiwania palindromów jest algorytmem naiwnym. Rozkłada on dany łańcuch znakowy s na wszystkie możliwe podłańcuchy p o długości nie mniejszej niż 2 znaki i sprawdza następnie, czy dadzą się przedstawić w postaci ww R lub wxw R. Sprawdzenie polega na porównywaniu znaków od początku i od końca podłańcucha. W tym celu wykorzystuje się dwa indeksy. Jeden z nich ustawia się na pierwszym znaku podłańcucha p, a drugi na ostatnim. Następnie porównujemy wskazywane przez te indeksy znaki podłańcucha p. Jeśli znaki są różne, to podłańcuch p nie jest palindromem. Jeśli porównywane znaki są równe, to indeksy przesuwamy lewy w prawo, a prawy w lewo. Jeśli indeksy się miną, to zachodzi jedna z dwóch równości: p = ww R, lub p = wxw R W takim przypadku p jest palindromem. Wyszukanie wszystkich palindromów zawartych w łańcuchu s proponowaną metodą posiada sześcienną klasę złożoności obliczeniowej O(n 3 ), gdzie n jest długością łańcucha s.

Wyszukiwanie palindromów Algorytm naiwny wyszukiwania palindromów Wejście: s łańcuch tekstowy. Wyjście: Wszystkie palindromy zawarte w łańcuchu s. Elementy pomocnicze: i,j - indeksy znaków w łańcuchu s, i,j N N - długość łańcucha s, n N i P prawy indeks, i P N i L lewy indeks, i L N

K01: n s LISTA KROKÓW K02: Dla i = 0,1,...,n - 2, wykonuj K03...K10 ; przeglądamy łańcuch s K03: Dla j = i+2, i+3,...,n- 1: wykonuj K04...K10 K04: il i ; lewy indeks na pierwszym znaku podsłowa K05: ip j - 1 ; prawy indeks na ostatnim znaku podsłowa K06: Dopóki il < ip wykonuj K07...K09 ; sprawdzamy, czy podsłowo jest palindromem K07: Jeśli s[il] s[ip], to następny obieg pętli K03 K08: il il + 1 ; lewy indeks przesuwamy w prawo K09: ip ip - 1 ; a prawy w lewo K10: Pisz s[i,j] ; wyprowadzamy znaleziony palindrom K11: Zakończ

Program Program generuje 40 znakowy łańcuch zbudowany ze znaków {A,B,C,D}, wyszukuje w nim wszystkie palindromy i wypisuje je z odpowiednim przesunięciem.

Rozwiązanie nr 2 Drugie podejście do rozwiązania problemu wyszukiwania wszystkich palindromów w łańcuchu znakowym s opiera się na własnościach palindromów. Przedstawiony tutaj algorytm został opracowany w 1975 przez Glenna Manachera z Computer Center and Department of Information Engineering, University of Illinois, Chicago, IL. Do opisu algorytmu Manachera wprowadzimy kilka nowych pojęć. Niech p P będzie palindromem parzystym o postaci p P = ww R, gdzie w jest niepustym podłańcuchem. Niech p N będzie palindromem nieparzystym o postaci p N = wxw R. Promieniem r p palindromu p będziemy nazywali długość podsłowa w, czyli r p = w Palindrom parzysty p P posiada zawsze długość p P = 2r p. Palindrom nieparzysty p N posiada zawsze długość p N = 2r p + 1. Środkiem palindromu p jest pozycja i s = r p jest to pozycja pierwszego znaku za słowem w (można również definiować środek palindromu jako pozycję ostatniego znaku podsłowa w, lecz sądzę, iż nasz sposób jest lepszy, gdyż nie wymaga wprowadzania żadnych zmian dla palindromów nieparzystych) Dla palindromu parzystego środek wypadnie na pierwszym znaku w R, natomiast dla palindromu nieparzystego środek wypadnie na znaku X: p P [r p ] = w R [0] p N [r p ] = X

Algorytm Manachera nie wyznacza wszystkich palindromów, jak robi to algorytm naiwny, lecz maksymalne palindromy, których środki występują na kolejnych pozycjach znakowych przeszukiwanego łańcucha s. Dzięki takiemu podejściu redukujemy złożoność obliczeniową fazy przeszukiwania łańcucha s. Mając maksymalny palindrom możemy bez problemów wyznaczyć zawarte w nim podpalindromy. Wykorzystujemy tutaj własność symetrii palindromu: Przykład: r p palindrom parzysty palindrom nieparzysty 4 ABCDDCBA ABCDADCBA 3 BCDDCB BCDADCB 2 CDDC CDADC 1 DD DAD

Dla danego łańcucha s algorytm Manachera tworzy tablicę dwuwymiarową R.: R[0,...] promienie palindromów parzystych R[1,...] promienie palindromów nieparzystych Indeksy tych tablic określają kolejne pozycje znakowe w łańcuchu s, natomiast elementy tablic zawierają maksymalne promienie palindromów o środkach na danej pozycji znakowej.

Używając w odpowiedni sposób tablicy R oraz własności symetrii palindromu algorytm Manachera wykorzystuje sprytnie informację o wcześniej wyznaczonych promieniach palindromów maksymalnych do wyszukiwania następnych palindromów. Otóż po wyznaczeniu promienia r p palindromu na pozycji i-tej w łańcuchu s, sprawdzane są promienie palindromów na kolejnych pozycjach poprzedzających pozycję i-tą w obszarze podsłowa w tutaj algorytm wymaga dwóch wersji osobnej dla palindromów parzystych i osobnej dla nieparzystych. Zasada jest identyczna dla obu wersji. Rozważmy zatem możliwe przypadki (dla palindromu parzystego):

Na pozycji i - k, k = 1,2,...,r p, promień palindromu wynosi 0 czyli nie istnieje palindrom o środku na pozycji i - k. Skoro tak, to przez symetrię wnioskujemy, iż na pozycji lustrzanej i + krównież nie będzie żadnego palindromu. Pozycja i + k możne zostać pominięta przy dalszym wyszukiwania palindromów.

Na pozycji i - k jest palindrom o promieniu r < r p - k. Taki palindrom w całości zawiera się wewnątrz rozważanego palindromu i co więcej, nie styka się z jego brzegiem. Poprzez symetrię wnioskujemy, iż na pozycji i + k również musi występować taki sam palindrom, którego już dalej nie da się rozszerzyć. Pozycji i + k nie musimy już dalej sprawdzać.

Na pozycji i - k jest palindrom o promieniu r > r p - k. Taki palindrom wykracza z lewej strony poza obszar rozważanego palindromu. Na pozycji i + k znajduje się palindrom o promieniu r = r p - k i palindromu tego nie da się już rozszerzyć. Wyjaśnienie tego faktu jest bardzo proste gdyby palindrom na pozycji i + k posiadał większy promień niż wyliczone r, to również z uwagi na symetrię przeglądany palindrom posiadałby promień większy od r p, a przecież jest to palindrom maksymalny. Pozycję i + k również możemy pominąć. Pozostał ostatni przypadek na pozycji i - k występuje palindrom o promieniu r = r p - k. Taki sam palindrom musi być na pozycji i + k, jednakże w tym przypadku palindrom ten może być rozszerzalny. Pozycję i + k musimy zatem sprawdzić na obecność palindromu o promieniu większym od r.

Z powyższych rozważań otrzymujemy następujący algorytm działający w czasie liniowym O(n): Algorytm Manachera wyszukiwania palindromów Wejście: s łańcuch tekstowy. Wyjście: Wszystkie palindromy zawarte w łańcuchu s. Elementy pomocnicze: j - indeksuje wymiar tablicy R. Wartość 0 dotyczy palindromów parzystych, wartość 1 dotyczy palindromów nieparzystych, j N k-zmienna pomocnicza do indeksowania środków palindromów wewnętrznych, k rp - wyznaczany promień palindromu maksymalnego, rp n- długość łańcucha s, n N R- tablica dwuwymiarowa, pierwszy wymiar określa rodzaj palindromu, drugi wymiar zawiera indeksy od 0 do n, R N N N

LISTA KROKÓW K01: n s ; obliczamy długość łańcucha s K02: s w1 + s + w2 ; na początku i na końcu s dodajemy wartowników, w1 w2 K03: Dla j = 0,1 wykonuj K04...K17 ; wyznaczamy promienie palindromów parzystych i nieparzystych K04: R[j,0] 0 ; pierwszy promień jest zawsze zerowy K05: i 1 ; ustawiamy i na pierwszym znaku s za wartownikiem w1 K06: rp 0 ; początkowy promień palindromu jest zerowy K07: Dopóki i n, wykonuj K08...K17 ; przechodzimy przez kolejne środki palindromów K08: Dopóki s[i - rp - 1] = s[i + j + rp], wykonuj rp rp + 1 ;wyznaczamy promień maksymalnego palindromu o środku na pozycji i-tej K09: R[j,i] rp ; wyliczony promień zapamiętujemy w tablicy R K10: k 1 ; przeglądamy promienie wcześniejszych palindromów wewnętrznych K11: Jeśli R[j,i - k] = rp - k, to idź do K16 ; sprawdzamy ostatni przypadek K12: Jeśli k rp, to idź do K16 ; musimy być wewnątrz palindromu K13: R[j,i + k] min(r[j,i - k],rp - k) ; wyznaczamy promień lustrzanego palindromu wewnętrznego K14: k k + 1 ; przechodzimy do następnego palindromu wewnętrznego K15: Idź do K11 K16: rp max(rp - k,0) ; wyznaczamy promień początkowy palindromu K17: i i + k ; pomijamy wyliczone palindromy lustrzane K18: s s[1:n] ; usuwamy wartowników w1 i w2 z łańcucha s K19: Dla i = 1,2,...,n wykonuj K20...K21 ; wyprowadzamy kolejne palindromy parzyste i nieparzyste K20: Dla j = 0,1 wykonuj K21 K21: Dla rp = R[j,i], R[j,i ]- 1,...,1 pisz s[i - rp - 1:i + 2rp + j] K22: Zakończ

Program Program generuje 40 znakowy łańcuch zbudowany ze znaków {A,B,C,D}, wyszukuje w nim wszystkie palindromy i wypisuje je z odpowiednim przesunięciem.

Szyfr Cezara

Szyfr Cezara Szyfrowanie tekstów (ang. text encryption) ma na celu ukrycie ważnych informacji przed dostępem do nich osób niepowołanych. Historia kodów szyfrujących sięga czasów starożytnych. Już tysiące lat temu egipscy kapłani stosowali specjalny system hieroglifów do szyfrowania różnych tajnych wiadomości. Szyfr Cezara (ang. Ceasar's Code lub Ceasar's Cipher) jest bardzo prostym szyfrem podstawieniowym (ang. substitution cipher). Szyfry podstawieniowe polegają na zastępowaniu znaków tekstu jawnego (ang. plaintext) innymi znakami przez co zawarta w tekście informacja staje się nieczytelna dla osób niewtajemniczonych. Współcześnie szyfrowanie stanowi jedną z najważniejszych dziedzin informatyki to dzięki niej stał się możliwy handel w Internecie, funkcjonują banki ze zdalnym dostępem do kont, powstał podpis elektroniczny oraz bezpieczne łącza transmisji danych. Przykładów zastosowania jest bez liku i dokładne omówienie tej dziedziny wiedzy leży daleko poza możliwościami tego artykułu.

Szyfr Cezara został nazwany na cześć rzymskiego imperatora Juliusza Cezara, który stosował ten sposób szyfrowania do przekazywania informacji o znaczeniu wojskowym. Szyfr polega na zastępowaniu liter alfabetu A...Z literami leżącymi o trzy pozycje dalej w alfabecie: Tek st jaw ny A B C D E F G H I J K L M N O P Q R S T U V W X Y Z Szy fr Cez ara D E F G H I J K L M N O P Q R S T U V W X Y Z A B C Ostatnie trzy znaki X, Y i Z nie posiadają następników w alfabecie przesuniętych o trzy pozycje. Dlatego umawiamy się, iż alfabet "zawija się" i za literką Z następuje znów litera A. Teraz bez problemu znajdziemy następniki X A, Y B i Z C.

Przykład: Zaszyfrować zdanie: NIEPRZYJACIEL JEST BARDZO BLISKO. Poszczególne literki tekstu jawnego zastępujemy literkami szyfru Cezara zgodnie z powyższą tabelką kodu. Spacje oraz inne znaki nie będące literami pozostawiamy bez zmian: NIEPRZYJACIEL JEST BARDZO BLISKO QLHSUCBMDFLHO MHVW EDUGCR EOLVNR Deszyfrowanie tekstu zaszyfrowanego kodem Cezara polega na wykonywaniu operacji odwrotnych. Każdą literę kodu zamieniamy na literę leżącą o trzy pozycje wcześniej w alfabecie.

Szyfr Cezara Szyfr Cezara A B C D E F G H I J K L M N O P Q R S T U V W X Y Z Tekst jawny X Y Z A B C D E F G H I J K L M N O P Q R S T U V W Podobnie jak poprzednio trzy pierwsze znaki szyfru Cezara nie posiadają bezpośrednich odpowiedników liter leżących o trzy pozycje wcześniej, ponieważ alfabet rozpoczyna się dopiera od pozycji literki D. Rozwiązaniem jest ponowne "zawinięcie" alfabetu tak, aby przed literą A znalazły się trzy ostatnie literki X, Y i Z. Do wyznaczania kodu literek przy szyfrowaniu i deszyfrowaniu posłużymy się operacjami modulo. Operacja modulo jest resztą z dzielenia danej liczby przez moduł. Wynik jest zawsze mniejszy od modułu. U nas moduł będzie równy 26, ponieważ tyle mamy liter alfabetu. Jeśli c jest kodem ASCII dużej litery alfabetu (rozważamy tylko teksty zbudowane z dużych liter), to szyfrowanie kodem Cezara polega na wykonaniu następującej operacji arytmetycznej: c = 65 + (c - 62) mod 26 Deszyfrowanie polega na zamianie kodu wg wzoru: c = 65 + (c - 42) mod 26

Algorytm szyfrowania tekstu kodem Cezara Wejście: Łańcuch tekstowy s Wyjście: Łańcuch tekstowy s zaszyfrowany kodem Cezara Elementy pomocnicze: i-indeks, i N kod(x)- zwraca kod litery x znak(x)- zmienia kod x na odpowiadający mu znak ASCII

LISTA KROKÓW K01: Dla i=0,1, s -1 wykonuj K02 K03 ;przeglądamy kolejne znaki tekstu K02: Jeśli s[i]< A v s[i] > Z, to następny obieg pętli K01 ;pomijamy znaki nie będące literami A...Z K03: s[i]<- znak (65+(kod(s[i])-62)mod26) ;szyfrujemy szyfrem Cezara K04: Pisz s K05: Zakończ

Program Program odczytuje wiersz znaków. Zamienia litery małe na duże i szyfruje kodem Cezara wyświetlając wynik.

Algorytm deszyfrowania tekstu zaszyfrowanego kodem Cezara Wejście: Łańcuch tekstowy s zaszyfrowany kodem Cezara Wyjście: Tekst jawny Elementy pomocnicze: i-indeks, i N kod(x)- zwraca kod litery x znak(x)- zmienia kod x na odpowiadający mu znak ASCII LISTA KROKÓW K01: Dla i=0,1, s -1 wykonuj K02 K03 ;przetwarzamy kolejne znaki tekstu K02: Jeśli s[i]< A v s[i] > Z, to następny obieg pętli K01 ;pomijamy znaki nie będące literami A...Z K03: s[i]<- znak (65+(kod(s[i])-42)mod26) ;deszyfrujemy K04: Pisz s K05: Zakończ

Program Program odczytuje wiersz znaków zaszyfrowanych szyfrem Cezara, deszyfruje je i wypisuje tekst jawny.

Szyfr przestawieniowy

Szyfr przestawieniowy (ang. transposition cifer) polega na zamianie położenia znaków tworzących tekst, przez co wiadomość staje się nieczytelna dla niewtajemniczonego odbiorcy. W zaszyfrowanym tekście znajdują się wszystkie znaki tekstu jawnego. Zaczniemy od najprostszych szyfrów przestawieniowych.

Przestawianie dwóch sąsiednich liter W tym rodzaju szyfru tekst dzielimy na pary znaków. Następnie w każdej parze zamieniamy ze sobą litery, Przykład: tekst = ALA MA KOCURKA BURKA I PIESKA BIESKA pary = AL A MA K OC UR KA B UR KA I P IE SK A BI ES KA zamiana = LA A AM K CO RU AK B RU AK I P EI KS A IB SE AK szyfr = LA AAMK CORUAKB RUAKI P EIKS AIBSEAK Tekst da się podzielić na pary, jeśli zawiera parzystą liczbę znaków. W przeciwnym razie ostatnia para jest niepełna. W takiej niepełnej parze liter oczywiście nie zamieniamy miejscami. Zwróć uwagę, iż ten szyfr jest symetryczny. Jeśli poddamy szyfrowaniu tekst poprzednio zaszyfrowany, to otrzymamy z powrotem tekst jawny.

Algorytm szyfrowania przestawieniowego ze zamianą liter w parach Wejście Łańcuch tekstowy s, który zawiera tekst poddawany szyfrowaniu lub deszyfrowaniu Wyjście: Zaszyfrowany łańcuch s Elementy pomocnicze: i- indeks, i N

LISTA KROKÓW K01: i <- 0 rozpoczynamy od pierwszego znaku K02: Dopóki i+1 < s wykonuj K03 K04 K03: s[i]<-> s[i+1] zamieniamy znaki w parze K04: i <- i+2 przesuwamy się do następnej pary znaków K05: Zakończ

Program Program wczytuje wiersz tekstu, szyfruje go przez zamianę liter w parach i wyświetla wynik.

Dodawanie dużych liczb

Problem Dodać do siebie dwie dowolnie duże, dodatnie liczby całkowite, przedstawione w postaci łańcucha cyfr. Problem rozwiążemy w sposób szkolny (profesjonalne algorytmy wymagają innego podejścia). Dodawane liczby musimy wyrównać do ostatnich cyfr: 21638626396236623668969866232198 95832808595775579737342988203408934789797363

Dodawanie rozpoczniemy od ostatnich cyfr łańcuchów. Stosujemy przy tym poznane w szkole podstawowej zasady dodawania dwóch liczb. Dodajemy ostatnie cyfry. W łańcuchu wynikowym umieszczamy ostatnią cyfrę wyniku. Natomiast pierwsza cyfra wyniku staje się przeniesieniem do następnej pozycji: 1 21638626396236623668969866232198 + 95832808595775579737342988203408934789797363 1

W następnym kroku dodajemy do siebie dwie kolejne cyfry oraz przeniesienie. Do łańcucha wynikowego wpisujemy na przedostatniej pozycji ostatnią cyfrę wyniku, a pierwsza cyfra wyniku staje się przeniesieniem na dalszą pozycję. 1 21638626396236623668969866232198 + 95832808595775579737342988203408934789797363 61 Jeśli w jednym z łańcuchów skończą się zbyt wcześnie cyfry, to przyjmujemy, że posiada on resztę cyfr równych 0. Sprowadza się to wtedy do dodawania przeniesień do pozostałych cyfr drugiego łańcucha. Gdy wszystkie cyfry zostaną przetworzone, a przeniesienie ma wartość większą od 0, to umieszczamy je na początku łańcucha wynikowego jako pierwszą cyfrę wyniku

Przy dodawaniu cyfr musimy pamiętać, że są one przechowywane w łańcuchach w postaci kodów ASCII: Cyfra Kod ASCII 0 48 1 49 2 50 3 51 4 52 5 53 6 54 7 55 8 56 9 57 Dlatego w celu otrzymania wartości cyfry należy od jej kodu odjąć 48, a przy otrzymywaniu kodu znaku z wartości cyfry należy do niej dodać 48.

Algorytm dodawania dwóch dowolnie dużych, nieujemnych liczb całkowitych Wejście: s1,s2 dodawane łańcuchy z cyframi Wyjście: s3 łańcuch wynikowy, który zawiera cyfry sumy Elementy pomocnicze: p przeniesienie z poprzedniej pozycji, p є Z w wynik dodawania, w є N i,j indeksy w łańcuchach s1 i s2, i,j є Z k licznik pętli, k є Z n długość krótszego z łańcuchów s1 i s2, n є Z kod(x) zwraca kod znaku x znak(x) zamienia kod x na odpowiadający mu znak ASCII

Lista kroków: K01: i s1 ; wyznaczamy długości łańcuchów K02: j s2 K03: n i ; w n wyznaczamy długość krótszego z łańcuchów K04: Jeśli j < i, to n j K05: p 0 ; zerujemy przeniesienie K06: s3 "" ; zerujemy łańcuch wyniku s3 K07: Dla k = 1,2,...n: wykonuj K08...K12 ;przebiegamy wstecz przez cyfry łańcuchów K08: w kod(s1[i]) + kod(s2[j]) + p - 96 ; obliczamy sumę cyfr i przeniesienia. 96 = 2 x 48 K09: i i - 1 ; ; cofamy indeksy o 1 pozycję dla kolejnego obiegu K10: j j - 1 K11: p w div 10 ; obliczamy przeniesienie do następnej pozycji K12: s3 znak((w mod 10) + 48) + s3 ; cyfrę sumy dołączamy do wyniku K13: Dopóki i > 0 wykonuj K14...K17 ; jeśli w s1 pozostały cyfry K14: w kod(s1[i]) + p - 48 ; to dodajemy do nich tylko przeniesienia K15: i i - 1 K16: p w div 10 K17: s3 znak((w mod 10) + 48) + s3 K18 Dopóki j > 0 wykonuj K19...K22 ; to samo dla s2 K19: w kod(s2[j]) + p - 48; K20: j j - 1 K21: p w div 10 K22: s3 znak((w mod 10) + 48) + s3 K23 Jeśli p > 0, to s3 znak(p + 48) + s3 K24: Jeśli s3 = "", to s3 = "0" ; jeśli wynik nie zawiera cyfr, to s1 i s2 były puste. K25: Zakończ ; wynik dodawania w s3 jeśli jest przeniesienie, to jest ono pierwszą cyfrą wyniku

Mnożenie dużych liczb

Problem 1 Pomnożyć dowolnie dużą nieujemną liczbę całkowitą przez nieujemną liczbę całkowitą względnie małą, np. 32 bitową Naszym zadaniem jest znalezienie iloczynu: W=a*b gdzie: a liczba duża, b-liczba mała Liczba mała b rozkłada się na sumę potęg liczby 2 mnożonych przez kolejne bity bi liczby b: b=b 31 2 31 +b 30 +2 30 +...+b 2 2 2 +b 1 2 1 +b 0 2 0

Teraz możemy zapisać: W=a* (b 31 2 31 +b 30 +2 30 +...+b 2 2 2 +b 1 2 1 +b 0 2 0) W=a*b 31 2 31 +a*b 30 +2 30 +...+a*b 2 2 2 +a*b 1 2 1 +a*b 0 2 0 Na pierwszy rzut oka otrzymany wzór wydaje się mało przydatny. Jednakże pozory mylą. Zapiszmy to nieco inaczej : W=b 31 2 31 a+b 30 +2 30 a+...+b 3 2 3 a+b 2 2 2 +b 1 2 1 a+b 0 2 0 a W=b 31 2 31 a+b 30 +2 30 a+...+b 3 8a+b 2 4a+b 1 2a+b 0 a

W powyższym wzorze b i to i-ty bit mniejszej liczby. Natomiast kolejne iloczyny 2 i a bardzo łatwo oblicza się dynamicznie za pomocą dodawania, ponieważ, co łatwo zauważyć, każdy kolejny iloczyn jest dwa razy większy od poprzedniego.: a 0 =a a 1 =2a=a 0 +a 0 a 2 =4a=a 1 +a 1 a 3 =8a=a 2 +a 2... a 30 =2 30 a=a 29 +a 29 a 31 =2 31 a=a 30 +a 30 Iloczyny dodajemy do wyniku W, jeśli odpowiedni bit b i jest równy 1. W całym tym postępowaniu wykonywane są tylko dodawania dużych liczb, które zostały opisane w poprzednim rozdziale. Bity z liczby b możemy łatwo wydzielać za pomocą operacji koniunkcji i przesuwów

Algorytm mnożenia dowolnie dużej liczby nieujemnej przez małą liczbę nieujemną Wejście: a duża liczba jako łańcuch znakowy b mała liczba, bє N Wyjście: w łańcuch wynikowy, który zawiera cyfry iloczynu ab a zawartość nieokreślona b zawiera zero Elementy pomocnicze: dodaj(x,y) dodaje dwie duże liczby x i y jako łańcuchy i zwraca wynik jako łańcuch Lista kroków: K01: w "0" ; zerujemy wynik K02: Jeśli (b and 1) = 1, to w dodaj(w,a) ; jeśli bit b i = 1, to dodaj a i do w K03: b b shr 1 ; przesuń bity w b o jedną pozycję w prawo K04: Jeśli b = 0, to zakończ ; reszta bitów jest zerowa, kończymy K05: a dodaj(a,a) ; oblicz kolejne a i K06: Idź do K02 ; kontynuuj pętlę

Problem 2 Obliczyć wartość iloczynu dwóch dowolnie dużych nieujemnych liczb całkowitych. Postąpimy zgodnie z algorytmem "szkolnym" (profesjonalne algorytmy wymagają innego podejścia). Liczby zapisujemy jedna nad drugą umówmy się, że dłuższą liczbę zapisujemy u góry, a krótszą na dole: x 95832808595775579737342988203408934789797363 21638626396236623668969866232198

Następnie tworzymy kolejne iloczyny częściowe górnej liczby przez cyfry liczby dolnej. Iloczyny te są przesunięte w lewo zgodnie z pozycją mnożącej cyfry: x 95832808595775579737342988203408934789797363 21638626396236623668969866232198 + 766662468766204637898743905627271478318378904 862495277361980217636086893830680413108176267 0 958328085957755797373429882034089347897973630 0 191665617191551159474685976406817869579594726 000............................................................... 574996851574653478424057929220453608738784178 00000000000000000000000000000 958328085957755797373429882034089347897973630 00000000000000000000000000000 191665617191551159474685976406817869579594726 0000000000000000000000000000000 2073690341706041464574292083419814736706959241205382993813776933584

Algorytm mnożenia dwóch dowolnie dużych nieujemnych liczb całkowitych Wejście: a,b liczby podane w postaci łańcuchów znakowych Wyjście: w łańcuch wynikowy, który zawiera cyfry iloczynu ab Elementy pomocnicze: c łańcuch pomocniczy dla iloczynu częściowego z łańcuch zawierający dodawane zera na końcu iloczynów częściowych n zawiera liczbę cyfr w b, n є N i wskazuje pozycję cyfr w b przez które mnożymy a, i єn dodaj(x,y) dodaje dwie duże liczby x i y jako łańcuchy i zwraca wynik jako łańcuch mnóż(x,y) zwraca łańcuch z iloczynem liczby dużej x jako łańcucha znakowego i liczby małej y, y є N kod(x) zwraca kod znaku x.

PROGRAMY