JustPaste.it

Algorytmy wyszukujące - najczęstszy element

cbb689712f6bd4665e0a5a72a0a2f866.gif

Zadanie jest następujące:

W n elementowym zbiorze znaleźć element, który powtarza się najczęściej

Pierwszym, narzucającym się rozwiązaniem jest podejście bezpośrednie. Wybieramy ze zbioru kolejne elementy i zliczamy ich wystąpienia. Wynikiem jest element, który występował najczęściej. Policzmy czasową złożoność obliczeniową takiego algorytmu:

Wybór n elementów wymaga n operacji. Po każdym wyborze musimy wykonać n porównań wybranego elementu z elementami zbioru w celu zliczenia ilości jego wystąpień. Daje to wynik:

T(n) = n2

Zatem algorytm w tej postaci posiada klasę złożoności O(n2). W dalszych rozdziałach zastanowimy się nad sposobami poprawy tego wyniku. (Zadanie o podobnej treści pojawiło się na maturze z informatyki w 2006 roku).

53bc88a43a3a7b3a0fcac951c52a55c9.gif

Dane wejściowe

n - ilość elementów w przeszukiwanym zbiorze.  n d6be7bb707cc7402f2cbc99047293e85.gif N
d[ ] - zbiór, w którym poszukujemy najczęstszego elementu.

Dane wyjściowe

wn - wartość elementu powtarzającego się najczęściej.
pn - pierwsza pozycja elementu najczęstszego. pn d6be7bb707cc7402f2cbc99047293e85.gif N,   1 253581e7ecfb29d44e1fae4a87bc3892.gif pn 253581e7ecfb29d44e1fae4a87bc3892.gif n
ln - liczba wystąpień najczęstszego elementu, ln d6be7bb707cc7402f2cbc99047293e85.gif N,   1 253581e7ecfb29d44e1fae4a87bc3892.gif ln 253581e7ecfb29d44e1fae4a87bc3892.gif n

Zmienne pomocnicze

i, j - zmienne licznikowe pętli. i, j d6be7bb707cc7402f2cbc99047293e85.gif N
licznik - licznik wystąpień elementu
d81d67a7f7c9dba62066ea9ab78e5dc4.gif
krok 1: wn e05d44a79f6a40737cedbb08f9389fe1.gif d[1];  pn e05d44a79f6a40737cedbb08f9389fe1.gif 1;  ln e05d44a79f6a40737cedbb08f9389fe1.gif 1
krok 2: Dla i = 1,2,...,n: wykonuj kroki 3...5
krok 3:     licznik e05d44a79f6a40737cedbb08f9389fe1.gif 0
krok 4:     Dla j = 1,2,...,n:  jeśli d[i] = d[j],  to  licznik e05d44a79f6a40737cedbb08f9389fe1.gif licznik + 1
krok 5:     Jeśli licznik > ln ,  to   wn e05d44a79f6a40737cedbb08f9389fe1.gif d[i];  pn e05d44a79f6a40737cedbb08f9389fe1.gif iln e05d44a79f6a40737cedbb08f9389fe1.gif licznik
krok 6: Zakończ algorytm
abdeb70c6a2b9a19b9ddc766e9670377.gif

Algorytm wyszukiwania najczęściej pojawiającego się elementu w zbiorze rozpoczynamy od inicjalizacji zmiennych, których zawartość będzie wynikiem pracy algorytmu.

Do wn trafia pierwszy element zbioru - tymczasowo będzie to najczęstszy element. W pn umieszczamy pozycję tego elementu, czyli 1. Do ln zapisujemy liczbę wystąpień, też 1.

Rozpoczynamy pętlę nr 1, która wybiera ze zbioru kolejne elementy. W zmiennej licznik będziemy zliczać ilość wystąpień elementu d[i]. Dokonuje tego wewnętrzna pętla nr 2, która przegląda kolejne elementy zbioru i jeśli są równe elementowi d[i], zwiększa o 1 stan licznika. Po zakończeniu tej pętli w zmiennej licznik mamy liczbę wystąpień w zbiorze elementu d[i].

Jeśli licznik zawiera wartość większą od ilości powtórzeń tymczasowego elementu ln, to za nowy tymczasowy element przyjmujemy d[i]. Do wn trafia wartość elementu, do pn zapisujemy numer jego pozycji, czyli i, a do ln zapisujemy wyznaczoną w zmiennej licznik liczbę powtórzeń.

Na końcu pętli nr 1 zwiększamy i o 1, czyli przechodzimy do kolejnego elementu w zbiorze i operację zliczania powtarzamy.

Po zakończeniu pętli nr 1 w zmiennej wn mamy wartość najczęściej powtarzającego się elementu, w pn jest pozycja jego pierwszego pojawienia się w zbiorze, a w ln mamy wyznaczoną ilość wystąpień.

Algorytm jest bardzo prosty w działaniu, lecz mało efektywny - niektóre elementy są zliczane wielokrotnie, a niektóre zupełnie niepotrzebnie. Usuwając te wady usprawnimy algorytm, co jest celem następnego rozdziału. W programowaniu często obowiązuje zasada:

Efektywność algorytmu jest odwrotnie proporcjonalna do jego złożoności. Wynika stąd, iż proste algorytmy mogą być mało efektywne, podczas gdy algorytmy złożone działają bardzo szybko pomijając operacje zbędne.

Jednakże dla małej ilości danych (do 5000) przedstawione rozwiązanie jest całkiem skuteczne i, ze względu na swą prostotę, warte stosowania.

a00c8908551c8f56c29064f2a0686392.gif
ec1a9d02539b773d49f3670066e6d7ac.gif    
   
   

dd737b0069e91026213835e3c8d1bee8.gif

Poniższe, przykładowe programy są praktyczną realizacją omawianego w tym rozdziale algorytmu. Zapewne można je napisać bardziej efektywnie. To już twoje zadanie. Dokładny opis stosowanych środowisk programowania znajdziesz we wstępie. Programy przed opublikowaniem w serwisie edukacyjnym zostały dokładnie przetestowane. Jeśli jednak znajdziesz jakąś usterkę (co zawsze może się zdarzyć), to prześlij o niej informację do autora. Pozwoli to ulepszyć nasze artykuły. Będziemy Ci za to wdzięczni.

 
       

Program generuje zbiór 100 liczb pseudolosowych z zakresu od 0 do 9, a następnie wyszukuje wśród nich liczbę powtarzającą się najczęściej.

Efekt uruchomienia programu
Demonstracja wyszukiwania najczęstszego elementu
------------------------------------------------
(C)2006 mgr Jerzy Wałaszek I LO w Tarnowie

5 0 (4) 8 1 7 8 8 6 0 2 9 9 0 (4) (4) (4) 3 (4) 0
9 8 7 3 3 5 2 8 2 6 (4) 5 (4) 1 6 1 (4) 2 3 0
6 1 (4) 9 1 7 9 8 1 2 9 6 9 5 0 7 1 (4) 5 5
2 (4) (4) 8 1 5 3 3 2 (4) 6 6 5 8 0 8 2 1 6 1
3 3 1 2 2 1 9 9 0 3 1 6 (4) 5 5 8 8 0 0 5

wn = 4, pn = 3, ln = 14

KONIEC. Naciśnij dowolny klawisz...

9b04c5353f78950e3ff3917453d50b37.gif
// Wyszukiwanie najczęstszego elementu
//-------------------------------------
// (C)2006 mgr Jerzy Wałaszek
// I LO w Tarnowie
//-------------------------------------

program searchmf1;

{$APPTYPE CONSOLE}

const

N = 100; // liczba elementów w zbiorze
M = 9; // górny zakres elementów

var
d : array[1..N] of cardinal;
i,j,licznik,ln,pn,wn : cardinal;

begin
writeln('Demonstracja wyszukiwania najczestszego elementu');
writeln('------------------------------------------------');
writeln('(C)2006 mgr Jerzy Walaszek I LO w Tarnowie');
writeln;

// Generujemy zbiór liczb pseudolosowych

randomize;
for i := 1 to N do d[i] := random(M + 1);

// Wyszukujemy najczęstszy element

wn := d[1]; pn := 1; ln := 1;
for i := 1 to N do
begin

licznik := 0;
for j := 1 to N do if d[i] = d[j] then inc(licznik);
if licznik > ln then
begin

wn := d[i]; pn := i; ln := licznik;
end;
end;

// Prezentujemy wyniki

for i := 1 to N do
if
d[i] = wn then write(' (', d[i], ')') else write(' ', d[i], ' ');
writeln;
writeln('wn = ', wn, ', pn = ', pn, ', ln = ', ln);

// Gotowe

writeln;
writeln('Koniec, nacisnij klawisz Enter...');
readln;
end.
ca9eb151286adb520d6443c154c6db95.gif
// Wyszukiwanie najczęstszego elementu
//-------------------------------------
// (C)2006 mgr Jerzy Wałaszek
// I LO w Tarnowie
//-------------------------------------

#include <iostream>

using namespace std;

const int N = 100; // liczba elementów w zbiorze
const int M = 9; // górny zakres elementów

int main(void)
{
unsigned d[N],i,j,licznik,ln,pn,wn;

cout << "Demonstracja wyszukiwania najczestszego elementu\n"
"------------------------------------------------\n"
"(C)2006 mgr Jerzy Walaszek I LO w Tarnowie\n\n"
;

// Generujemy zbiór liczb pseudolosowych

srand((unsigned)time(NULL));
for(i = 0; i < N; i++) d[i] = rand() % (M + 1);

// Wyszukujemy najczęstszy element

wn = d[0]; pn = 0; ln = 1;
for(i = 0; i < N; i++)
{
licznik = 0;
for(j = 0; j < N; j++) if(d[i] == d[j]) licznik++;
if(licznik > ln)
{
wn = d[i]; pn = i; ln = licznik;
}
}

// Prezentujemy wyniki

for(i = 0; i < N; i++)
if(d[i] == wn)
cout << " (" << d[i] << ")";
else
cout << " " << d[i] << " ";
cout << "\nwn = " << wn << ", pn = " << pn + 1 << ", ln = " << ln << "\n\n";

// Gotowe

system("pause"); return 0;
}
1d439143204027616f68ac078b30f4cb.gif
' Wyszukiwanie najczęstszego elementu
'-------------------------------------
' (C)2006 mgr Jerzy Wałaszek
' I LO w Tarnowie
'-------------------------------------

Module Module1

Sub Main()
Const N = 100 ' liczba elementów w zbiorze
Const M = 9 ' górny zakres elementów

Dim d(N), i, j, licznik, ln, pn, wn As UInteger

Console.WriteLine("Demonstracja wyszukiwania najczęstszego elementu")
Console.WriteLine("------------------------------------------------")
Console.WriteLine("(C)2006 mgr Jerzy Wałaszek I LO w Tarnowie")
Console.WriteLine()

' Generujemy zbiór liczb pseudolosowych

Randomize()
For i = 1 To N : d(i) = Int(Rnd(1) * (M + 1)) : Next

' Wyszukujemy najczęstszy element

wn = d(1) : pn = 1 : ln = 1
For i = 1 To N
licznik = 0
For j = 1 To N
If d(i) = d(j) Then licznik += 1
Next
If
licznik > ln Then
wn = d(i) : pn = i : ln = licznik
End If
Next


' Prezentujemy wyniki

For i = 1 To N
If d(i) = wn Then
Console.Write(" ({0})", d(i))
Else
Console.Write(" {0} ", d(i))
End If
Next

Console.WriteLine()
Console.WriteLine("wn = {0}, pn = {1}, ln = {2}", wn, pn, ln)
Console.WriteLine()

' Gotowe

Console.WriteLine("KONIEC. Naciśnij dowolny klawisz...")
Console.ReadLine()

End Sub

End Module
05025df806be9d7766395c1e3729085c.gif
# -*- coding: cp1250 -*-
# Wyszukiwanie najczęstszego elementu
#-------------------------------------
# (C)2006 mgr Jerzy Wałaszek
# I LO w Tarnowie
#-------------------------------------

import random

N = 100 # liczba elementów w zbiorze
M = 9 # górny zakres elementów

d = []

print "Demonstracja wyszukiwania najczestszego elementu"
print "------------------------------------------------"
print "(C)2006 mgr Jerzy Walaszek I LO w Tarnowie"
print

# Generujemy zbiór liczb pseudolosowych

for i in range(N): d.append(random.randint(0, M))

# Wyszukujemy najczęstszy element

wn, pn, ln = d[0], 0, 1
for i in range(N):
licznik = d.count(d[i])
if licznik > ln:
wn, pn, ln = d[i], i, licznik

# Prezentujemy wyniki

for i in d:
if i == wn:
print " (%d)" % i,
else:
print " %d " % i,
print
print

print "wn = %d, pn = %d, ln = %d" % (wn, pn + 1, ln)

# Gotowe

print
raw_input("Koniec, nacisnij dowolny klawisz...")
0946c1602a8493c905eadf115daac409.gif
<html>
<head>
</head>
<body>
<div align=
"center">
<form style=
"BORDER-RIGHT: #ff9933 1px outset; PADDING-RIGHT: 4px;
BORDER-TOP: #ff9933 1px outset; PADDING-LEFT: 4px;
PADDING-BOTTOM: 1px; BORDER-LEFT: #ff9933 1px outset;
PADDING-TOP: 1px; BORDER-BOTTOM: #ff9933 1px outset;
BACKGROUND-COLOR: #ffcc66"
name="frmSearchMF">
<h4 id=
"out_t" style="TEXT-ALIGN: center">
Demonstracja wyszukiwania najczęstszego elementu
</h4>
<p style=
"TEXT-ALIGN: center">
(C)2006 mgr Jerzy Wałaszek<br>
I LO w Tarnowie
</p>
<hr>
<p style=
"TEXT-ALIGN: center">
<input type=
"button" value="Szukaj" name="B1" onclick="main();">
</p>
<p style=
"TEXT-ALIGN: center" id="t_out">...</p>
</form>

<script language=
javascript>

// Wyszukiwanie najczęstszego elementu
//-------------------------------------
// (C)2006 mgr Jerzy Wałaszek
// I LO w Tarnowie
//-------------------------------------

function main()
{
var N = 100; // liczba elementów w zbiorze
var M = 9; // górny zakres elementów
var d = new Array(N);
var i,j,licznik,ln,pn,wn,t;

// Generujemy zbiór liczb pseudolosowych

for(i = 0; i < N; i++) d[i] = Math.floor(Math.random() * (M + 1));

// Wyszukujemy najczęstszy element

wn = d[0]; pn = 0; ln = 1;
for(i = 0; i < N; i++)
{
licznik = 0;
for(j = 0; j < N; j++) if(d[i] == d[j]) licznik++;
if(licznik > ln)
{
wn = d[i]; pn = i; ln = licznik;
}
}

// Prezentujemy wyniki

t = "";
for(i = 0; i < N; i++)
if(d[i] == wn)
t += "<b><font color=red>(" + d[i] + ")</font></b> ";
else
t += " &nbsp;" + d[i] + " ";
t += "<br><br>wn = " + wn + ", pn = " + (pn + 1) + ", ln = " + ln;

// Gotowe

document.getElementById("t_out").innerHTML = t;
}

</script>
</div>
</body>
</html>
 
Dokument ten rozpowszechniany jest zgodnie z zasadami licencji
GNU Free Documentation License.

 

Źródło: mgr Jerzy Wałaszek