Dynamic array and set

This commit is contained in:
Antti H S Laaksonen 2016-12-31 14:25:58 +02:00
parent 4cceee01ab
commit d7ca9e76fe
1 changed files with 117 additions and 109 deletions

View File

@ -1,38 +1,40 @@
\chapter{Data structures} \chapter{Data structures}
\index{tietorakenne@tietorakenne} \index{data structure}
\key{Tietorakenne} A \key{data structure} is a way to store
on tapa säilyttää tietoa tietokoneen muistissa. data in the memory of the computer.
Sopivan tietorakenteen valinta on tärkeää, It is important to choose a suitable
koska kullakin rakenteella on omat data structure for a problem,
vahvuutensa ja heikkoutensa. because each data structure has its own
Tietorakenteen valinnassa oleellinen kysymys on, advantages and disadvantages.
mitkä operaatiot rakenne toteuttaa tehokkaasti. The crucial question is: which operations
are efficient in the chosen data structure?
Tämä luku esittelee keskeisimmät This chapter introduces the most important
C++:n standardikirjaston tietorakenteet. data structures in the C++ standard library.
Valmiita tietorakenteita kannattaa käyttää It is a good idea to use the standard library
aina kun mahdollista, whenever possible,
koska se säästää paljon aikaa toteutuksessa. because it will save a lot of time.
Myöhemmin kirjassa tutustumme erikoisempiin Later in the book we will learn more sophisticated
rakenteisiin, joita ei ole valmiina C++:ssa. data structures that are not available
in the standard library.
\section{Dynaaminen taulukko} \section{Dynamic array}
\index{vektori@vektori} \index{dynamic array}
\index{vector}
\index{vector@\texttt{vector}} \index{vector@\texttt{vector}}
\key{Dynaaminen taulukko} on taulukko, A \key{dynamic array} is an array whose
jonka kokoa voi muuttaa size can be changed during the execution
ohjelman suorituksen aikana. of the code.
C++:n tavallisin dynaaminen taulukko The most popular dynamic array in C++ is
on \key{vektori} (\texttt{vector}). the \key{vector} structure (\texttt{vector}),
Sitä voi käyttää hyvin samalla tavalla that can be used almost like a regular array.
kuin tavallista taulukkoa.
Seuraava koodi luo tyhjän vektorin The following code creates an empty vector and
ja lisää siihen kolme lukua: adds three elements to it:
\begin{lstlisting} \begin{lstlisting}
vector<int> v; vector<int> v;
@ -41,7 +43,7 @@ v.push_back(2); // [3,2]
v.push_back(5); // [3,2,5] v.push_back(5); // [3,2,5]
\end{lstlisting} \end{lstlisting}
Tämän jälkeen vektorin sisältöä voi käsitellä taulukon tavoin: After this, the elements can be accessed like in a regular array:
\begin{lstlisting} \begin{lstlisting}
cout << v[0] << "\n"; // 3 cout << v[0] << "\n"; // 3
@ -49,8 +51,9 @@ cout << v[1] << "\n"; // 2
cout << v[2] << "\n"; // 5 cout << v[2] << "\n"; // 5
\end{lstlisting} \end{lstlisting}
Funktio \texttt{size} kertoo, montako alkiota vektorissa on. The function \texttt{size} returns the number of elements in the vector.
Seuraava koodi käy läpi ja tulostaa kaikki vektorin alkiot: The following code iterates through
the vector and prints all elements in it:
\begin{lstlisting} \begin{lstlisting}
for (int i = 0; i < v.size(); i++) { for (int i = 0; i < v.size(); i++) {
@ -59,7 +62,7 @@ for (int i = 0; i < v.size(); i++) {
\end{lstlisting} \end{lstlisting}
\begin{samepage} \begin{samepage}
Vektorin voi käydä myös läpi lyhyemmin näin: A shorter way to iterate trough a vector is as follows:
\begin{lstlisting} \begin{lstlisting}
for (auto x : v) { for (auto x : v) {
@ -68,9 +71,9 @@ for (auto x : v) {
\end{lstlisting} \end{lstlisting}
\end{samepage} \end{samepage}
Funktio \texttt{back} hakee vektorin viimeisen alkion, The function \texttt{back} returns the last element
ja funktio \texttt{pop\_back} poistaa vektorin in the vector, and
viimeisen alkion: the function \texttt{pop\_back} removes the last element:
\begin{lstlisting} \begin{lstlisting}
vector<int> v; vector<int> v;
@ -81,47 +84,48 @@ v.pop_back();
cout << v.back() << "\n"; // 5 cout << v.back() << "\n"; // 5
\end{lstlisting} \end{lstlisting}
Vektorin sisällön voi antaa myös sen luonnissa: The following code creates a vector with five elements:
\begin{lstlisting} \begin{lstlisting}
vector<int> v = {2,4,2,5,1}; vector<int> v = {2,4,2,5,1};
\end{lstlisting} \end{lstlisting}
Kolmas tapa luoda vektori on ilmoittaa Another way to create a vector is to give the number
vektorin koko ja alkuarvo: of elements and the initial value for each element:
\begin{lstlisting} \begin{lstlisting}
// koko 10, alkuarvo 0 // size 10, initial value 0
vector<int> v(10); vector<int> v(10);
\end{lstlisting} \end{lstlisting}
\begin{lstlisting} \begin{lstlisting}
// koko 10, alkuarvo 5 // size 10, initial value 5
vector<int> v(10, 5); vector<int> v(10, 5);
\end{lstlisting} \end{lstlisting}
Vektori on toteutettu sisäisesti tavallisena taulukkona. The internal implementation of the vector
Jos vektorin koko kasvaa ja taulukko jää liian pieneksi, uses a regular array.
varataan uusi suurempi taulukko, johon kopioidaan If the size of the vector increases and
vektorin sisältö. the array becomes too small,
Näin tapahtuu kuitenkin niin harvoin, että vektorin a new array is allocated and all the
funktion \texttt{push\_back} aikavaativuus on elements are copied to the new array.
keskimäärin $O(1)$. However, this doesn't happen often and the
time complexity of
\texttt{push\_back} is $O(1)$ on average.
\index{merkkijono@merkkijono} \index{string}
\index{string@\texttt{string}} \index{string@\texttt{string}}
Myös \key{merkkijono} (\texttt{string}) on dynaaminen taulukko, Also the \key{string} structure (\texttt{string})
jota pystyy käsittelemään lähes samaan is a dynamic array that can be used almost like a vector.
tapaan kuin vektoria. In addition, there is special syntax for strings
Merkkijonon käsittelyyn liittyy lisäksi erikoissyntaksia that is not available in other data structures.
ja funktioita, joita ei ole muissa tietorakenteissa. Strings can be combined using the \texttt{+} symbol.
Merkkijonoja voi yhdistää toisiinsa \texttt{+}-merkin avulla. The function $\texttt{substr}(k,x)$ returns the substring
Funktio $\texttt{substr}(k,x)$ erottaa merkkijonosta that begins at index $k$ and has length $x$.
osajonon, joka alkaa kohdasta $k$ ja jonka pituus on $x$. The function $\texttt{find}(\texttt{t})$ finds the position
Funktio $\texttt{find}(\texttt{t})$ etsii kohdan, where a substring \texttt{t} appears in the string.
jossa osajono \texttt{t} esiintyy merkkijonossa.
Seuraava koodi esittelee merkkijonon käyttämistä: The following code presents some string operations:
\begin{lstlisting} \begin{lstlisting}
string a = "hatti"; string a = "hatti";
@ -133,37 +137,41 @@ string c = b.substr(3,4);
cout << c << "\n"; // tiva cout << c << "\n"; // tiva
\end{lstlisting} \end{lstlisting}
\section{Joukkorakenne} \section{Set structure}
\index{joukko@joukko} \index{set}
\index{set@\texttt{set}} \index{set@\texttt{set}}
\index{unordered\_set@\texttt{unordered\_set}} \index{unordered\_set@\texttt{unordered\_set}}
\key{Joukko} on tietorakenne, A \key{set} is a data structure that
joka sisältää kokoelman alkioita. contains a collection of elements.
Joukon perusoperaatiot ovat alkion lisäys, The basic operations in a set are element
haku ja poisto. insertion, search and removal.
C++ sisältää kaksi C++ contains two set implementations:
toteutusta joukolle: \texttt{set} ja \texttt{unordered\_set}. \texttt{set} and \texttt{unordered\_set}.
Rakenne \texttt{set} perustuu tasapainoiseen The structure \texttt{set} is based on a balanced
binääripuuhun, ja sen operaatioiden aikavaativuus binary tree and the time complexity of its
on $O(\log n)$. operations is $O(\log n)$.
Rakenne \texttt{unordered\_set} pohjautuu hajautustauluun, The structure \texttt{unordered\_set} uses a hash table,
ja sen operaatioiden aikavaativuus on keskimäärin $O(1)$. and the time complexity of its operations is $O(1)$ on average.
Usein on makuasia, kumpaa joukon toteutusta käyttää. The choice which set implementation to use
Rakenteen \texttt{set} etuna on, että se säilyttää is often a matter of taste.
joukon alkioita järjestyksessä ja tarjoaa The benefit in the \texttt{set} structure
järjestykseen liittyviä funktioita, is that it maintains the order of the elements
joita \texttt{unordered\_set} ei sisällä. and provides functions that are not available
Toisaalta \texttt{unordered\_set} on usein nopeampi rakenne. in \texttt{unordered\_set}.
On the other hand, \texttt{unordered\_set} is
often more efficient.
Seuraava koodi luo lukuja sisältävän joukon ja The following code creates a set
esittelee sen käyttämistä. that consists of integers,
Funktio \texttt{insert} lisää joukkoon alkion, and shows how to use it.
funktio \texttt{count} laskee alkion määrän joukossa The function \texttt{insert} adds an element to the set,
ja funktio \texttt{erase} poistaa alkion joukosta. the function \texttt{count} returns how many times an
element appears in the set,
and the function \texttt{erase} removes an element from the set.
\begin{lstlisting} \begin{lstlisting}
set<int> s; set<int> s;
@ -178,11 +186,12 @@ cout << s.count(3) << "\n"; // 0
cout << s.count(4) << "\n"; // 1 cout << s.count(4) << "\n"; // 1
\end{lstlisting} \end{lstlisting}
Joukkoa voi käsitellä muuten suunnilleen samalla tavalla A set can be used mostly like a vector,
kuin vektoria, mutta joukkoa ei voi indeksoida but it is not possible to access
\texttt{[]}-merkinnällä. the elements using the \texttt{[]} notation.
Seuraava koodi luo joukon, tulostaa sen The following code creates a set,
alkioiden määrän ja käy sitten läpi kaikki alkiot. prints the number of elements in it, and then
iterates through all the elements:
\begin{lstlisting} \begin{lstlisting}
set<int> s = {2,5,6,8}; set<int> s = {2,5,6,8};
cout << s.size() << "\n"; // 4 cout << s.size() << "\n"; // 4
@ -191,14 +200,15 @@ for (auto x : s) {
} }
\end{lstlisting} \end{lstlisting}
Tärkeä joukon ominaisuus on, An important property of a set is
että tietty alkio voi esiintyä siinä that all the elements are distinct.
enintään kerran. Thus, the function \texttt{count} always returns
Niinpä funktio \texttt{count} palauttaa aina either 0 (the element is not in the set)
arvon 0 (alkiota ei ole joukossa) tai 1 (alkio on joukossa) or 1 (the element is in the set),
ja funktio \texttt{insert} ei lisää alkiota and the function \texttt{insert} never adds
uudestaan joukkoon, jos se on siellä valmiina. an element to the set if it is
Seuraava koodi havainnollistaa asiaa: already in the set.
The following code illustrates this:
\begin{lstlisting} \begin{lstlisting}
set<int> s; set<int> s;
@ -211,14 +221,13 @@ cout << s.count(5) << "\n"; // 1
\index{multiset@\texttt{multiset}} \index{multiset@\texttt{multiset}}
\index{unordered\_multiset@\texttt{unordered\_multiset}} \index{unordered\_multiset@\texttt{unordered\_multiset}}
C++ sisältää myös rakenteet C++ also contains the structures
\texttt{multiset} ja \texttt{unordered\_multiset}, \texttt{multiset} and \texttt{unordered\_multiset}
jotka toimivat muuten samalla tavalla kuin \texttt{set} that work otherwise like \texttt{set}
ja \texttt{unordered\_set}, and \texttt{unordered\_set}
mutta sama alkio voi esiintyä but they can contain multiple copies of an element.
monta kertaa joukossa. For example, in the following code all copies
Esimerkiksi seuraavassa koodissa of the number 5 are added to the set:
kaikki luvun 5 kopiot lisätään joukkoon:
\begin{lstlisting} \begin{lstlisting}
multiset<int> s; multiset<int> s;
@ -227,22 +236,21 @@ s.insert(5);
s.insert(5); s.insert(5);
cout << s.count(5) << "\n"; // 3 cout << s.count(5) << "\n"; // 3
\end{lstlisting} \end{lstlisting}
Funktio \texttt{erase} poistaa The function \texttt{erase} removes
kaikki alkion esiintymät all instances of an element
\texttt{multiset}-rakenteessa: from a \texttt{multiset}:
\begin{lstlisting} \begin{lstlisting}
s.erase(5); s.erase(5);
cout << s.count(5) << "\n"; // 0 cout << s.count(5) << "\n"; // 0
\end{lstlisting} \end{lstlisting}
Usein kuitenkin tulisi poistaa Often, only one instance should be removed,
vain yksi esiintymä, which can be done as follows:
mikä onnistuu näin:
\begin{lstlisting} \begin{lstlisting}
s.erase(s.find(5)); s.erase(s.find(5));
cout << s.count(5) << "\n"; // 2 cout << s.count(5) << "\n"; // 2
\end{lstlisting} \end{lstlisting}
\section{Hakemisto} \section{Map structure}
\index{hakemisto@hakemisto} \index{hakemisto@hakemisto}
\index{map@\texttt{map}} \index{map@\texttt{map}}