Anna Sobocińska Sylwia Piwońska

Podobne dokumenty
(3 kwiecień 2014) Marika Pankowska Kamila Pietrzak

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

Liczby całkowite i rzeczywiste

MACIERZE. Sobiesiak Łukasz Wilczyńska Małgorzata

Podstawy algorytmiki i programowania - wykład 6 Sortowanie- algorytmy

[12] Metody projektowania algorytmów (dziel i rządź, programowanie dynamiczne i algorytmy zachłanne).

Sortowanie przez wstawianie Insertion Sort

Algorytm selekcji Hoare a. Łukasz Miemus

Transponowanie macierzy Mnożenie macierzy Potęgowanie macierzy Wyznacznik macierzy

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

Wstęp do programowania

r. Tablice podstawowe operacje na tablicach

PDF stworzony przez wersję demonstracyjną pdffactory Pro Program 15

Wstęp do programowania

Programowanie i struktury danych

Informacje wstępne #include <nazwa> - derektywa procesora umożliwiająca włączenie do programu pliku o podanej nazwie. Typy danych: char, signed char

Podstawowe algorytmy i ich implementacje w C. Wykład 9

O podstawowych operacjach na tablicach. Mateusz Ziółkowski, MBiU II

Algorytmy sortujące i wyszukujące

8. Wektory. Przykłady Napisz program, który pobierze od użytkownika 10 liczb, a następnie wypisze je w kolejności odwrotnej niż podana.

Wstęp do programowania

Definicja. Ciąg wejściowy: Funkcja uporządkowująca: Sortowanie polega na: a 1, a 2,, a n-1, a n. f(a 1 ) f(a 2 ) f(a n )

Algorytmy sortujące. sortowanie kubełkowe, sortowanie grzebieniowe

Luty 2001 Algorytmy (4) 2000/2001

operacje porównania, a jeśli jest to konieczne ze względu na złe uporządkowanie porównywanych liczb zmieniamy ich kolejność, czyli przestawiamy je.

INFORMATYKA Z MERMIDONEM. Programowanie. Moduł 5 / Notatki

Program 14. #include <iostream> #include <ctime> using namespace std;

lekcja 8a Gry komputerowe MasterMind

Wstęp do programowania

Wstęp do Informatyki

1,3,4,2,3,4,0,1,4,5,0. Wówczas największa suma trzech kolejnych liczb (zaznaczone na czerwono) wynosi:

Rozwiązanie. #include <cstdlib> #include <iostream> using namespace std;

Sortowanie bąbelkowe - wersja nr 1 Bubble Sort

Algorytmika i programowanie. Wykład 2 inż. Barbara Fryc Wyższa Szkoła Informatyki i Zarządzania w Rzeszowie

Programowanie Proceduralne

Rekurencja. Dla rozwiązania danego problemu, algorytm wywołuje sam siebie przy rozwiązywaniu podobnych podproblemów. Przykład: silnia: n! = n(n-1)!

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

Część 4 życie programu

- - Ocena wykonaniu zad3. Brak zad3

Wstęp do Informatyki zadania ze złożoności obliczeniowej z rozwiązaniami

Metodyki i Techniki Programowania 2

Programowanie komputerowe. Zajęcia 1

Algorytmy i Struktury Danych.

Strategia "dziel i zwyciężaj"

Sortowanie przez scalanie

Ćwiczenie 3 z Podstaw programowania. Język C++, programy pisane w nieobiektowym stylu programowania. Zofia Kruczkiewicz

Kontrola przebiegu programu

Wstęp do programowania

Podstawy Informatyki. Sprawność algorytmów

4. Funkcje. Przykłady

Czym jest całka? Całkowanie numeryczne

Opis zagadnieo 1-3. Iteracja, rekurencja i ich realizacja

Analiza algorytmów zadania podstawowe

Zajęcia nr 2 Programowanie strukturalne. dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej

Tablice. Monika Wrzosek (IM UG) Podstawy Programowania 96 / 119

Zmienne i struktury dynamiczne

Mechanizm dziedziczenia

Podstawy Programowania Podstawowa składnia języka C++

Algorytmy przeszukiwania wzorca

Algorytmy, reprezentacja algorytmów.

Wstęp do programowania

Laboratorium nr 7 Sortowanie

Tablice są typem pochodnym. Poniżej mamy przykłady deklaracji różnych tablic:

wykład IV uzupełnienie notatek: dr Jerzy Białkowski Programowanie C/C++ Język C, a C++. wykład IV dr Jarosław Mederski Spis Język C++ - wstęp

Zajęcia nr 5 Algorytmy i wskaźniki. dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej

np. dla p=1 mamy T1(N) N/2 średni czas chybionego wyszukiwania z prawdopodobieństwem q:

tablica: dane_liczbowe

7. Pętle for. Przykłady

Dariusz Brzeziński. Politechnika Poznańska, Instytut Informatyki

Struktury danych i złożoność obliczeniowa Wykład 2. Prof. dr hab. inż. Jan Magott

Program znajduje największa lub najmniejsza z podanych liczb. Liczby podajemy dopóki nam sie nie znudzi.

Informatyka A. Algorytmy

wagi cyfry pozycje

Podstawy informatyki. Elektrotechnika I rok. Język C++ Operacje na danych - wskaźniki Instrukcja do ćwiczenia

Jeszcze o algorytmach

Programowanie - wykład 4

do instrukcja while (wyrażenie);

1 Podstawy c++ w pigułce.

Pytanie 1. Pytanie 2. Pytanie 3 WOJEWÓDZKI KONKURS INFORMATYCZNY. Treść pytania

Tablice jednowymiarowe

Konstrukcje warunkowe Pętle

Zaawansowane algorytmy i struktury danych

I - Microsoft Visual Studio C++

Wprowadzenie do algorytmiki

WYŻSZA SZKOŁA INFORMATYKI STOSOWANEJ I ZARZĄDZANIA

1 Wskaźniki. 1.1 Główne zastosowania wskaźników

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

Ćwiczenie 7 z Podstaw programowania. Język C++, programy pisane w nieobiektowym stylu programowania. Zofia Kruczkiewicz

Algorytmy i złożoności. Wykład 3. Listy jednokierunkowe

Inicjacja tablicy jednowymiarowej

Zadanie 1 Przygotuj algorytm programu - sortowanie przez wstawianie.

Podstawy algorytmiki i programowania - wykład 3 Funkcje rekurencyjne Wyszukiwanie liniowe i binarne w tablicy

WYKŁAD 9. Algorytmy sortowania elementów zbioru (tablic) Programy: c4_1.c... c4_3.c. Tomasz Zieliński

Algorytmy sortujące 1

Programowanie obiektowe W3

Instrukcje sterujące

Podstawy programowania skrót z wykładów:

Kolokwium ze wstępu do informatyki, I rok Mat. (Ściśle tajne przed godz. 10 : grudnia 2005.)

Algorytmy zrandomizowane

Programowanie komputerowe. Zajęcia 4

Transkrypt:

Anna Sobocińska Sylwia Piwońska

Problem Wyszukiwanie liniowe W n-elementowym zbiorze Z wyszukać element posiadający pożądane własności.

Wyszukiwanie liniowe (ang. linear search), zwane również sekwencyjnym (ang. sequential search) polega na przeglądaniu kolejnych elementów zbioru Z. Jeśli przeglądany element posiada odpowiednie własności (np. jest liczbą o poszukiwanej wartości), to zwracamy jego pozycję w zbiorze i kończymy. W przeciwnym razie kontynuujemy poszukiwania aż do przejrzenia wszystkich pozostałych elementów zbioru Z. W przypadku pesymistycznym, gdy poszukiwanego elementu nie ma w zbiorze lub też znajduje się on na samym końcu zbioru, algorytm musi wykonać przynajmniej n obiegów pętli sprawdzającej poszczególne elementy. Wynika z tego, iż pesymistyczna klasa złożoności obliczeniowej jest równa O(n), czyli jest liniowa stąd pochodzi nazwa metody wyszukującej. Często chcemy znaleźć wszystkie wystąpienia w zbiorze poszukiwanej wartości elementu. W takim przypadku algorytm na wejściu powinien otrzymywać dodatkowo pozycję (indeks) elementu, od którego ma rozpocząć wyszukiwanie. Pozycję tę przy kolejnym przeszukiwaniu podajemy zawsze o 1 większą od ostatnio znalezionej. Dzięki temu nowe poszukiwanie rozpocznie się tuż za poprzednio znalezionym elementem.

Algorytm wyszukiwania liniowego/sekwencyjnego Wejście: n liczba elementów w tablicy Z, n NZ tablica zawierająca elementy do przeszukania. Indeksy elementów rozpoczynają się od 0, a kończą na n-1p indeks pierwszego elementu Z, od którego rozpoczniemy poszukiwania. p Ck poszukiwana wartość, czyli tzw. klucz, wg którego wyszukujemy elementy w Z Wyjście: Pozycja elementu zbioru Z o kluczu k lub -1 w przypadku nie znalezienia elementu. Zmienne pomocnicze i przebiega przez kolejne indeksy elementów Z. i C

Lista kroków: K01:Dla i = p,p+1,...,n-1: wykonuj K02; przeglądamy kolejne elementy w zbiorzek02: Jeśli Z[i] = k, to zakończ z wynikiem i; jeśli napotkamy poszukiwany element, zwracamy jego pozycjęk03:zakończ z wynikiem -1; jeśli elementu nie ma w tablicy, zwracamy -1

Program Program odczytuje z pierwszego wiersza liczbę n. Z następnych n wierszy odczytywane jest n danych całkowitych. W ostatnim wierszu odczytywana jest liczba k, którą należy wyszukać wśród podanych n liczb. Program wypisuje numer pozycji w odczytanym ciągu liczb, na której znajduje się liczba k lub -1, jeśli liczby nie odnaleziono.

#include <iostream> using namespace std; int Szukaj(int T[], int n, int k, int p) for(int i = p; i < n; i++) if(t[i] == k) return i; return -1; int main() int * Z,n,k,i; cin >> n; Z = new int [n]; for(i = 0; i < n; i++) cin >> Z[i]; cin >> k; cout << endl << Szukaj(Z,n,k,0) << endl << endl; delete [] Z; system("pause"); return 0;

Program Program wypełnia 100 elementową tablicę Z całkowitymi liczbami pseudolosowymi z zakresu od 0 do 9. Następnie losuje nową liczbę pseudolosową z tego samego zakresu i znajduje wszystkie jej wystąpienia w Z przy pomocy wyszukiwania liniowego. Na końcu wyświetla wylosowaną liczbę oraz zawartość Z z zaznaczonymi jej wystąpieniami. Do zapamiętywania wystąpień służy druga tablica L o elementach logicznych. Jeśli i- ty element tej tablicy zawiera true, to w i-tym elemencie tablicy Z znajduje się poszukiwany element.

#include <iostream> #include <cstdlib> #include <time.h> using namespace std; int main() int Z[100],i,w; bool L[100]; srand((unsigned)time(null)); for(i = 0; i < 100; i++) Z[i] = rand() % 10; w = rand() % 10; for(i = 0; i < 100; i++) L[i] = (Z[i] == w); cout << w << endl << endl; for(i = 0; i < 100; i++) if(l[i]) cout << " ->"; else cout << " "; cout << Z[i]; cout << endl; system("pause"); return 0;

Wyszukiwanie max lub min Problem W n-elementowym zbiorze Z znaleźć element o maksymalnej (minimalnej) wartości. Zadanie znajdowania elementu maksymalnego lub minimalnego jest typowym zadaniem wyszukiwania, które rozwiązujemy przy pomocy algorytmu wyszukiwania liniowego. Za tymczasowy maksymalny(minimalny) element przyjmujemy pierwszy element zbioru. Następnie element tymczasowy porównujemy z kolejnymi elementami. Jeśli któryś z porównywanych elementów jest większy (mniejszy) od elementu tymczasowego, to za nowy tymczasowy element maksymalny (minimalny) przyjmujemy porównywany element zbioru. Gdy cały zbiór zostanie przeglądnięty, w elemencie tymczasowym otrzymamy element maksymalny (minimalny) w zbiorze. Poniżej podajemy algorytm wyszukiwania max. Wyszukiwanie min wykonuje się identycznie, zmianie ulega tylko warunek porównujący element tymczasowy z elementem zbioru w kroku K03.

Algorytm wyszukiwania elementu maksymalnego w zbiorze Wejście n liczba elementów w tablicy Z, n NZ tablica zawierająca elementy do zliczania. Indeksy elementów rozpoczynają się od 0, a kończą na n - 1. Wyjście: Wartość największego elementu zbioru. Zmienne pomocnicze i przebiega przez kolejne indeksy elementów Z. i Cmax Z tymczasowy element maksymalny Lista kroków: K01:max Z Z[0]; za tymczasowy element maksymalny bierzemy pierwszy elementk02:dla i = 1,2,...,n-1 wykonuj K03; przeglądamy następne elementy zbioruk03: Jeśli Z[i] > max Z, to max Z Z[i]; jeśli natrafimy na większy od max Z, to zapamiętujemy go w max Z K04:Zakończ z wynikiem max Z

Program #include <iostream> #include <iomanip> #include <cstdlib> #include <time.h> using namespace std; const int N = 15; int main() int Z[N],i,maxZ,minZ; srand((unsigned)time(null)); for(i = 0; i < N; i++) Z[i] = rand() % 10000; maxz = minz = Z[0]; for(i = 1; i < N; i++) if(z[i] > maxz) maxz = Z[i]; if(z[i] < minz) minz = Z[i]; for(i = 0; i < N; i++) cout << setw(5) << Z[i] << endl; cout << endl << setw(5) << minz << setw(5) << maxz << endl << endl; system("pause"); return 0;

Jednoczesne wyszukiwanie max i min Problem W n-elementowym zbiorze Z znaleźć element maksymalny i minimalny. Jeśli do wyszukiwania elementu max i min zastosujemy standardowy algorytm, to otrzymamy: Wejście n liczba elementów w tablicy Z, n NZ tablica zawierająca elementy do zliczania. Indeksy elementów rozpoczynają się od 0, a kończą na n - 1.Wyjście: Wartość najmniejszego i największego elementu w tablicy Z. Zmienne pomocnicze i przebiega przez kolejne indeksy elementów Z. i Cmax Z tymczasowy element maksymalny,min Z tymczasowy element minimalny

Numer Operacja Liczba wykonań 1 min Z Z[0] 1 2 max Z Z[0] 1 3 i 1 1 4 Jeśli i = n, to idź do 9 n 5 Jeśli Z[i] < min Z, to min Z Z[i] 6 Jeśli Z[i] > max Z, to max Z Z[i] n-1 n-1 7 i i + 1 n-1 8 Idź do 4 n-1 9 Pisz min Z, max Z 1 10 Zakończ 1

Zastanówmy się, czy można uzyskać lepszy wynik. Algorytm porównuje każdy element zbioru z min Z oraz z max Z. Tutaj tkwi nieefektywność. Obie operacje nr 5 i 6 są wykonywane po n - 1 razy, co daje w sumie 2n - 2 porównania w całym zbiorze. Wyobraźmy sobie, iż ze zbioru bierzemy parę 2 elementów i porównujemy je ze sobą. Element większy nie może być minimalnym, zatem nie musimy go już porównywać z min Z. Wystarczy porównanie z max Z. To samo dotyczy elementu mniejszego porównujemy go tylko z min Z. Otrzymujemy zysk poprzednio dwa elementy wymagały wykonania 4 porównań (każdy z min Z i max Z ). Teraz mamy: Jedno porównanie dwóch elementów, które rozdzieli je na element mniejszy i element większy. Element mniejszy porównujemy z min Z. Element większy porównujemy z max Z. Daje to 3 porównania zamiast 4. Ponieważ ze zbioru pobieramy po dwa kolejne elementy, to ich liczba musi być parzysta. Jeśli zbiór ma nieparzystą liczbę elementów, to po prostu dublujemy ostatni element i dostaniemy parzystą liczbę elementów. Porównanie pary elementów dzieli zbiór na dwa podzbiory zbiór elementów większych i mniejszych. W podzbiorze elementów większych szukamy elementu maksymalnego, a w podzbiorze elementów mniejszych szukamy minimalnego. Ponieważ ich liczebność jest o połowę mniejsza od liczebności zbioru wejściowego, to wykonamy mniej operacji porównań. Metoda rozwiązywania problemów przez podział na mniejsze części w informatyce nosi nazwę Dziel i Zwyciężaj (ang. Divide and Conquer). Dzięki niej często udaje się zmniejszyć złożoność obliczeniową wielu algorytmów.

Algorytm jednoczesnego wyszukiwania max i min w zbiorze Wejście n liczba elementów w tablicy Z, n NZ tablica zawierająca elementy do zliczania. Indeksy elementów rozpoczynają się od 0, a kończą na n - 1. Tablica musi umożliwiać dodanie elementu, jeśli n jest nieparzyste. Wyjście: Element minimalny i maksymalny w tablicy Z Zmienne pomocnicze i przebiega przez kolejne indeksy elementów Z. i Cmax Z tymczasowy element maksymalny max p pozycja tymczasowego elementu maksymalnego

Lista kroków: K01:Jeśli n mod 2 = 1, Z[n] Z[n-1]; jeśli nieparzysta liczba elementów, dublujemy ostatni K02:min Z największa liczba całkowita; inicjujemy min Z i max Z K03:max Z najmniejsza liczba całkowita K04:i 0 K05:Dopóki i < n wykonuj K06...K12; wybieramy pary kolejnych elementów K06: Jeśli Z[i] > Z[i+1], to idź do K10; rozdzielamy je na element mniejszy i większy K07: Jeśli Z[i] < min Z, to min Z Z[i]; Z[i] - mniejszy, Z[i+1] większy K08: Jeśli Z[i+1] > max Z, to max Z Z[i+1] K09: Idź do K12 K10: Jeśli Z[i] > max Z, to max Z Z[i]; Z[i] - większy, Z[i+1] mniejszy K11: Jeśli Z[i+1] < min Z, to min Z Z[i+1] K12: i i + 2; przechodzimy do następnej pary elementów K13:Pisz min Z, max Z ; wyprowadzamy wyniki K14:Zakończ

Program Program generuje 15 liczb pseudolosowych z zakresu od 0 do 9999. Wygenerowane liczby zapisuje w tablicy Z. Następnie wyszukuje liczbę najmniejszą i największą. Jako wynik jest wypisywana zawartość całej tablicy w 15 kolejnych wierszach, a w wierszu 17 podane zostają element minimalny i maksymalny.

#include <iostream> #include <iomanip> #include <cstdlib> #include <time.h> using namespace std; const int N = 15; int main() int Z[N+1],minZ,maxZ,i; srand((unsigned)time(null)); for(i = 0; i < N; i++) Z[i] = rand() % 10000; if(n % 2) Z[N] = Z[N-1]; minz = 10000; maxz = -1; for(i = 0; i < N; i += 2) if(z[i] > Z[i+1]) if(z[i] > maxz) maxz = Z[i]; if(z[i+1] < minz) minz = Z[i+1]; else if(z[i] < minz) minz = Z[i]; if(z[i+1] > maxz) maxz = Z[i+1]; for(i = 0; i < N; i++) cout << setw(4) << Z[i] << endl; cout << endl << minz << " : " << maxz << endl << endl; system("pause"); return 0;

Zastosowania wyszukiwania sortowanie przez wybór Problem Posortować rosnąco n-elementowy zbiór Z.

Zadanie sortowania polega na takim ułożeniu elementów zbioru Z, aby zachodził pomiędzy nimi porządek zdefiniowany odpowiednią relacją porządkującą. Porządek rosnący oznacza, iż w miarę posuwania się w głąb zbioru, wartości elementów stają się coraz większe nie napotkamy elementu mniejszego od któregokolwiek z elementów go poprzedzających w zbiorze. Relacją porządkującą jest relacja < lub przy dopuszczeniu elementów o równych wartościach jednakże wtedy nie jest określona kolejność elementów równych. Istnieje bardzo wiele różnych algorytmów sortowania (ang. Sorting Algorithms). W tym rozdziale przedstawimy bardzo prosty algorytm, który wykorzystuje liniowe wyszukiwanie (ang. linear search)elementu minimalnego w zbiorze sortowanie przez wybór (ang. Selection Sort). Zasada pracy tego algorytmu jest następująca: Wyszukujemy w zbiorze Z najmniejszy element min Z. Element najmniejszy w zbiorze posortowanym powinien znaleźć się na pierwszej pozycji. Zatem znaleziony element wymieniamy z elementem pierwszym. Dalej postępujemy identycznie ze zbiorem Z pomniejszonym o pierwszy element.. Znajdujemy kolejny element minimalny i wymieniamy go z elementem na pozycji drugiej. Sortowanie tym samym sposobem kontynuujemy dla kolejnych podzbiorów Z. Gdy otrzymamy podzbiór jednoelementowy (czyli gdy wykonamy n - 1 wyborów elementów minimalnych). Kolejno znajdowane elementy minimalne tworzą ciąg niemalejący to wyjaśnia skuteczność tej metody przy sortowaniu zbioru.

Algorytm sortowania przez wybór Wejście n liczba elementów w tablicy Z, n NZ tablica zawierająca elementy do posortowania. Wyjście: Tablica Z z posortowanymi rosnąco elementami Zmienne pomocnicze i, j przebiegają przez kolejne indeksy elementów Z. i, j Cmin Z tymczasowy element minimalny min p pozycja tymczasowego elementu minimalnego, min p

Lista kroków: K01:Dla i = 0,1,...,n-2 wykonuj K02...K08 K02: min Z Z[i]; tymczasowy element minimalny K03: min p i; oraz jego tymczasowa pozycja K04: Dla j = i+1,i+2,...,n-1 wykonuj K05...K07; w pozostałych elementach szukamy minimalnego K05: Jeśli Z[j] min Z, to kolejny obieg pętli K04...K07 K06: min Z Z[j]; znaleźliśmy, uaktualniamy min Z oraz min p K07: min p j K08: Z[i] Z[min p ]; zamieniamy znaleziony element z i- tym K09:Zakończ

Program Program wypełnia 200 elementową tablicę liczbami pseudolosowymi od 0 do 999. Następnie wyświetla zawartość tej tablicy przed sortowaniem, sortuje ją opisanym algorytmem sortowania przez wybór i na koniec wyświetla tablicę posortowaną.

#include <iostream> #include <iomanip> #include <cstdlib> #include <time.h> using namespace std; const int N = 200; int main() int Z[N],minZ,minp,i,j,x; srand((unsigned)time(null)); for(i = 0; i < N; i++) Z[i] = rand() % 1000; // Przed sortowaniem for(i = 0; i < N; i++) cout << setw(4) << Z[i]; cout << endl; // Sortowanie przez wybór for(i = 0; i < N - 1; i++) minz = Z[i]; minp = i; for(j = i + 1; j < N; j++) if(z[j] < minz) minz = Z[j]; minp = j; x = Z[i]; Z[i] = Z[minp]; Z[minp] = x; // Po sortowaniu for(i = 0; i < N; i++) cout << setw(4) << Z[i]; cout << endl; system("pause"); return 0;

Wyszukiwanie najczęstszej wartości w zbiorze dominanta Problem W n-elementowym zbiorze Z znaleźć wartość występującą najczęściej.

Rozwiązanie nr 1 Problem wyszukiwania najczęstszej wartości (ang. searching for the most frequent value), czyli tzw. dominanty zbioru, możemy rozwiązać na kilka różnych sposobów. Pierwszym, najprostszym podejściem jest metoda bezpośrednia naiwna: Przeglądamy kolejne elementy zbioru i zliczamy liczbę wystąpień ich wartości w zbiorze. Można to robić tak zapamiętujemy i-ty element i ustawiamy licznik wystąpień na 0. Następnie przeglądamy cały zbiór i, jeśli trafimy na element o takiej samej wartości, to licznik zwiększamy o 1. Po wykonaniu tej operacji porównujemy zawartość licznika z tymczasową maksymalną liczbą wystąpień (na początku algorytmu jest ona ustawiana na 0). Jeśli stan licznika jest większy, to zapamiętujemy go w tymczasowej maksymalnej liczbie wystąpień oraz zapamiętujemy wyszukiwaną wartość elementu. Gdy przeglądniemy w ten sposób i zliczymy wystąpienia wartości wszystkich elementów w zbiorze Z, to otrzymamy element powtarzający się najczęściej oraz ilość tych powtórzeń. Klasa złożoności obliczeniowej tak zdefiniowanego algorytmu jest równa O(n 2 ). Jeśli elementów jest niewiele (do około 5000) i szybkość działania nie gra istotnej roli, to rozwiązanie naiwne jest do przyjęcia

Algorytm znajdowania najczęstszej wartości wersja nr 1 Wejście n liczba elementów w tablicy Z, n NZ tablica do wyszukania najczęstszego elementu Elementy są liczbami całkowitymi. Indeksy od 0 do n - 1.. Wyjście: Element występujący najczęściej w Z oraz liczba jego wystąpień. Jeśli jest kilka elementów o takiej samej maksymalnej liczbie wystąpień, to algorytm zwraca pierwszy z nich, który został napotkany w zbiorze. Zmienne pomocnicze i, j przebiega przez kolejne indeksy elementów Z. i,j CL licznik wystąpień wartości elementu, L CW wartość elementu, której liczbę wystąpień w Z zliczamy. max W najczęstsza wartość elementów tablicy Zmax L liczba wystąpień wartości najczęstszej. max L C

Lista kroków: K01:max L 0; zerujemy maksymalną liczbę wystąpień K02:Dla i = 0,1,...,n - 1 wykonuj K03...K09; przeglądamy kolejne elementy tablicy Z K03: W Z[i]; zapamiętujemy poszukiwaną wartość elementu K04: L 0; zerujemy jej licznik wystąpień K05: Dla j = 0,1,...,n - 1 wykonuj K06; zliczamy wystąpienia K06: Jeśli Z[j] = W, to L L + 1 K07: Jeśli L max L, to następny obieg pętli K2; sprawdzamy, czy W jest tymczasowo najczęstsze K08: max L L; jeśli tak, zapamiętujemy liczbę wystąpień K09: max W W; oraz wartość W K10:Pisz max W, max L ; wypisujemy wyniki K11:Zakończ

Program Program umieszcza w tablicy Z 400 liczb pseudolosowych z zakresu od 0 do 99, wyznacza wartość występującą najczęściej, wyświetla zawartość tej tablicy zaznaczając wartości najczęstsze i wypisuje tę wartość oraz liczbę jej wystąpień.

#include <iostream> #include <iomanip> #include <cstdlib> #include <time.h> using namespace std; int main() const int N = 400; int Z[N],i,j,L,W,maxL,maxW; // Generujemy zawartość Z[] srand((unsigned)time(null)); for(i = 0; i < N; i++) Z[i] = rand() % 100; // Wyszukujemy najczęstszą wartość maxl = 0; for(i = 0; i < N; i++) W = Z[i]; L = 0; for(j = 0; j < N; j++) if(z[j] == W) L++; if(l > maxl) maxl = L; maxw = W; // Wypisujemy tablicę for(i = 0; i < N; i++) if(z[i] == maxw) cout << " >" << setw(2) << Z[i]; else cout << setw(4) << Z[i]; // Wypisujemy najczęstszy element // oraz liczbę wystąpień cout << endl << maxw << " : " << maxl << endl << endl; system("pause"); return 0;

Rozwiązanie nr 2 Podany powyżej algorytm jest bardzo prymitywny i wykonuje wiele niepotrzebnych działań. Postarajmy się je wyeliminować. Ze zbioru bierzemy KAŻDY element Z[i] i zliczamy wystąpienia jego wartości W w CAŁYM zbiorze Z. W ten sposób najczęstsza wartość max W zostanie zliczona max L 2 razy. Zatem pierwsze ulepszenie będzie polegało na tym, iż pobrany element W zbioru zliczamy tylko wtedy, gdy jest on różny od max W. Wynika z tego, iż na początku pracy algorytmu do max W musimy wpisać wartość różną od Z[0](dlaczego?). Każdy element Z[i] zliczamy w całym zbiorze. Tymczasem, jeśli wartość i-tego elementu wystąpiła wcześniej w zbiorze, to jest już zliczona. Jeśli nie wystąpiła wcześniej, to nie ma sensu jej tam szukać, nieprawdaż? W obu przypadkach wystarczy, jeśli zliczanie rozpoczniemy od pozycji i + 1 do końca zbioru. Elementy zliczone po prostu zliczymy ponownie, lecz w mniejszym zakresie. Elementy nowe zliczymy poprawnie, od miejsca ich pierwszego wystąpienia. Jeśli w trakcie działania algorytmu w max L mamy chwilową maksymalną liczbę wystąpień pewnej wartości max W, to zliczanie nowych elementów możemy przerwać po osiągnięciu pozycji n - max L. Jeśli nowy element występuje na tej lub dalszej pozycji w zbiorze Z, to liczba wystąpień jego wartości nie będzie już większa od max L, gdyż braknie elementów

Algorytm znajdowania najczęstszej wartości wersja nr 2 Wejście n liczba elementów w tablicy Z, n NZ tablica do wyszukania najczęstszego elementu Elementy są liczbami całkowitymi. Indeksy od 0 do n - 1.. Wyjście: Element występujący najczęściej w Z oraz liczba jego wystąpień. Jeśli jest kilka elementów o takiej samej maksymalnej liczbie wystąpień, to algorytm zwraca pierwszy z nich, który został napotkany w zbiorze. Zmienne pomocnicze i, j przebiega przez kolejne indeksy elementów Z. i, j CL licznik wystąpień wartości elementu, L CW wartość elementu, której liczbę wystąpień w Z zliczamy. max W najczęstsza wartość elementów tablicy Zmax L liczba wystąpień wartości najczęstszej. max L C

Lista kroków: K01:max L 0; licznik wystąpień najczęstszej wartości K02:max W Z[0] - 1; najczęstsza wartość - musi być różna od Z[0]! K03:i 0; rozpoczynamy zliczanie wartości elementów K04:Dopóki i < n - max L, wykonuj K05...K13; zliczamy do n-max L K05: W Z[i]; zapamiętujemy wartość bieżącego elementu K06: Jeśli W = max W, to idź do K13; jeśli jest równa max W, to pomijamy element Z[i] K07: L 1; Z[i] raz zliczony K08: Dla j = i+1,i+2,...,n-1 wykonuj K09; zliczanie rozpoczynamy od następnych elementówk09: Jeśli Z[j] = W, to L L + 1 K10: Jeśli L max L, to idź do K13; zliczyliśmy więcej niż max L? K11: max L L; jeśli tak, zapamiętujemy L w max L K12: max W W; oraz W w max W K13: i i + 1; przechodzimy do kolejnego elementu Z[i] K14:Pisz max W, max L ; wyprowadzamy wyniki K15:Zakończ

Program Program umieszcza w tablicy Z 400 liczb pseudolosowych z zakresu od 0 do 99, wyznacza wartość występującą najczęściej, wyświetla zawartość tej tablicy zaznaczając wartości najczęstsze i wypisuje tę wartość oraz liczbę jej wystąpień.

#include <iostream> #include <iomanip> #include <cstdlib> #include <time.h> using namespace std; int main() const int N = 400; int Z[N],i,j,L,W,maxL,maxW; // Generujemy zawartość Z[] srand((unsigned)time(null)); for(i = 0; i < N; i++) Z[i] = rand() % 100; // Wyszukujemy najczęstszą wartość maxl = 0; maxw = Z[0] - 1; for(i = 0; i < N - maxl; i++) W = Z[i]; if(maxw!= W) L = 1; for(j = i + 1; j < N; j++) if(z[j] == W) L++; if(l > maxl) maxl = L; maxw = W; // Wypisujemy tablicę for(i = 0; i < N; i++) if(z[i] == maxw) cout << " >" << setw(2) << Z[i]; else cout << setw(4) << Z[i]; // Wypisujemy najczęstszy element // oraz liczbę wystąpień cout << endl << maxw << " : " << maxl << endl << endl; system("pause"); return 0;

Rozwiązanie nr 3 Jeśli elementy zbioru tworzą spójny przedział wartości i przedział ten nie jest specjalnie duży, to do wyszukania wartości najczęstszej można zastosować następującą metodę. Tworzymy tablicę L, której elementy będą pełniły rolę liczników wystąpień wartości elementów z tablicy Z. Zakres indeksów w L możemy znaleźć wyszukując w tablicy Z wartość minimalną i maksymalną (można też z góry przydzielić odpowiednią liczbę liczników, gdy znamy zakres wartości elementów w przeszukiwanej tablicy Z). Zerujemy wszystkie liczniki w L i przeglądamy tablicę Z zwiększając o 1 liczniki w L, które odpowiadają wartościom przeglądanych elementów. W efekcie po zakończeniu przeglądania tablicy Z w L będziemy mieli informację o liczbie wystąpień każdej z wartości. Wyznaczamy w L element maksymalny. Wynikiem jest indeks, który określa wartość występującą najczęściej w Z oraz zawartość elementu L o tym indeksie, która określa ile razy dana wartość wystąpiła w Z. Tak określony algorytm wyszukiwania najczęstszego elementu posiada liniową klasę złożoności obliczeniowej O(m + n), gdzie m jest liczbą wartości elementów przeszukiwanego zbioru, a n jest liczbą jego elementów.

Algorytm znajdowania najczęstszej wartości wersja nr 3 Wejście n liczba elementów w tablicy Z, n NZ tablica do wyszukania najczęstszego elementu Elementy są liczbami całkowitymi. Indeksy od 0 do n - 1..min Z minimalna wartość w Z. max Z maksymalna wartość w Z. Wyjście: Element występujący najczęściej w Z oraz liczba jego wystąpień. Jeśli jest kilka elementów o takiej samej maksymalnej liczbie wystąpień, to algorytm w tej wersji zwraca najmniejszy z nich (jeśli pozostałe elementy są istotne, to można je odczytać z tablicy L porównując liczbę wystąpień z maksymalną). Zmienne pomocnicze i przebiega przez kolejne indeksy elementów Z. i CL tablica liczników wystąpień wartości elementów z Z. max L tymczasowy element maksymalny w Lmax p pozycja tymczasowego elementu maksymalnego w L

Lista kroków: K01:Utwórz L o rozmiarze max Z - min Z + 1; przygotowujemy liczniki wartości K02:Wyzeruj L; liczniki ustawiamy na 0 K03:Dla i = 0,1,...,n-1 wykonuj K04; zliczamy wystąpienia wartości elementówk04: Zwiększ o 1 L[Z[i] - min Z ]; w odpowiednich licznikach K05:max L L[0]; szukamy max w L K06:max p 0 K07:Dla i = 1,2,...,max Z -min Z wykonuj K08...K10 K08: Jeśli L[i] max L, to następny obieg pętli K07 K09: max L L[i]; zapamiętujemy wartość maksymalną K10: max p i; oraz jej pozycję K11:Pisz max p + min Z, max L ; wyprowadzamy najczęstszy element oraz liczbę jego wystąpień K12:Zakończ

Program Program umieszcza w tablicy Z 80 liczb pseudolosowych z zakresu od -9 do 9, wyświetla zawartość tej tablicy i wyznacza w niej wartość występującą najczęściej. Program wypisuje tę wartość oraz liczbę jej wystąpień w tablicy Z.

#include <iostream> #include <iomanip> #include <cstdlib> #include <time.h> using namespace std; const int N = 80; int main() int Z[N], * L,i,nL,maxZ,minZ,maxL,maxp; srand((unsigned)time(null)); // Przygotowujemy tablicę Z[] for(i = 0; i < N; i++) Z[i] = -9 + (rand() % 19); // Wyświetlamy tablicę Z[] for(i = 0; i < N; i++) cout << setw(4) << Z[i]; // Wyszukujemy w Z[] min i max if(z[0] > Z[1]) minz = Z[1]; maxz = Z[0]; else minz = Z[0]; maxz = Z[1]; for(i = 2; i < N; i += 2) if(z[i] > Z[i+1]) if(z[i] > maxz) maxz = Z[i]; if(z[i+1] < minz) minz = Z[i+1]; else if(z[i] < minz) minz = Z[i]; if(z[i+1] > maxz) maxz = Z[i+1]; // Przygotowujemy liczniki nl = maxz - minz + 1; L = new int[nl]; for(i = 0; i < nl; i++) L[i] = 0; // Zliczamy wystąpienia wartości z Z[] for(i = 0; i < N; i++) L[Z[i] - minz]++; // Szukamy najczęstszej wartości w L[] maxl = L[0]; maxp = 0; for(i = 0; i < nl; i++) if(l[i] > maxl) maxl = L[i]; maxp = i; // Wyświetlamy wyniki cout << endl << (maxp + minz) << " : " << maxl << endl << endl; delete [] L; system("pause"); return 0;

Rozwiązanie nr 4 Zbiór Z możemy posortować rosnąco. Wtedy elementy o równych wartościach znajdą się obok siebie. Teraz wystarczy przeglądnąć zbiór Z od początku do końca, zliczać powtarzające się wartości i zapamiętać tę wartość, która powtarza się najczęściej. Klasa złożoności obliczeniowej algorytmu w tej wersji zależy od zastosowanego algorytmu sortującego zbiór Z. Samo przeglądnięcie zbioru i wyłonienie najczęstszej wartości ma liniową klasę złożoności obliczeniowej O(n). Zaletą tego algorytmu jest to, iż elementy tablicy Z nie muszą być koniecznie liczbami całkowitymi. Mogą to być obiekty dowolnego typu.

Algorytm znajdowania najczęstszej wartości wersja nr 4 Wejście n liczba elementów w tablicy Z, n NZ tablica do wyszukania najczęstszego elementu Elementy są liczbami całkowitymi. Indeksy od 0 do n. Tablica powinna być posortowana rosnąco. Na końcu tablicy element Z[n] powinien być umieszczony wartownik o wartości innej niż wartość ostatniego elementu Z[n-1]. Wyjście: Element występujący najczęściej w Z oraz liczba jego wystąpień. Jeśli jest kilka elementów o takiej samej maksymalnej liczbie wystąpień, to algorytm w tej wersji zwraca najmniejszy z nich. Zmienne pomocnicze i przebiega przez kolejne indeksy elementów Z. i Cmax L liczba wystąpień najczęstszego elementu w Z, max L Cmax W wartość najczęstszego elementu w ZL licznik równych elementów, L C

Lista kroków: K02:max L 0; inicjujemy liczbę wystąpień na 0 K03:L 1; w L zliczamy pierwszy element K04:Dla i = 1,2,...,n wykonuj K05...K10; przeglądamy kolejne elementy aż do wartownika K05: Jeśli Z[i] = Z[i - 1], to idź do K10; dla równych elementów zwiększamy L o 1 K06: Jeśli L max L, to idź do K09; elementy nie są równe, sprawdzamy licznik L K07: max L L; jeśli L > max L, to zapamiętujemy L K08: max W Z[i - 1]; oraz wartość elementu K09: L 0; dla nowego elementu licznik L wystartuje od 1 K10: L L + 1; zliczamy elementy równe K11:Pisz max W, max L ; wypisujemy wyniki K12:Zakończ

Program #include <iostream> #include <iomanip> #include <cstdlib> #include <time.h> using namespace std; const int N = 200; int main() int Z[N + 1],maxL,maxW,minZ,minp,L,i,j,x; srand((unsigned)time(null)); // Inicjujemy tablicę Z[] for(i = 0; i < N; i++) Z[i] = rand() % 10; // Sortujemy tablicę Z[] for(i = 0; i < N - 1; i++) minz = Z[i]; minp = i; for(j = i + 1; j < N; j++) if(z[j] < minz) minz = Z[j]; minp = j; x = Z[i]; Z[i] = Z[minp]; Z[minp] = x; for(i = 0; i < N; i++) cout << setw(2) << Z[i]; cout << endl; // Dodajemy wartownika Z[N] = Z[N - 1] - 1; // Szukamy najczęstszej wartości maxl = 0; L = 1; for(i = 1; i <= N; i++) if(z[i]!= Z[i - 1]) if(l > maxl) maxl = L; maxw = Z[i - 1]; L = 0; L++; // Wyświetlamy wyniki cout << maxw << " : " << maxl << endl << endl; system ("pause"); return 0; // Wyświetlamy tablicę Z[]