Dynamic array and set
This commit is contained in:
parent
4cceee01ab
commit
d7ca9e76fe
226
luku04.tex
226
luku04.tex
|
@ -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}}
|
||||||
|
|
Loading…
Reference in New Issue