Maps and iterators
This commit is contained in:
		
							parent
							
								
									d7ca9e76fe
								
							
						
					
					
						commit
						2f9a1d8bac
					
				
							
								
								
									
										240
									
								
								luku04.tex
								
								
								
								
							
							
						
						
									
										240
									
								
								luku04.tex
								
								
								
								
							|  | @ -256,83 +256,80 @@ cout << s.count(5) << "\n"; // 2 | |||
| \index{map@\texttt{map}} | ||||
| \index{unordered\_map@\texttt{unordered\_map}} | ||||
| 
 | ||||
| \key{Hakemisto} on taulukon yleistys, | ||||
| joka sisältää kokoelman avain-arvo-pareja. | ||||
| Siinä missä taulukon avaimet ovat aina peräkkäiset | ||||
| kokonaisluvut $0,1,\ldots,n-1$, | ||||
| missä $n$ on taulukon koko, | ||||
| hakemiston avaimet voivat | ||||
| olla mitä tahansa tyyppiä | ||||
| eikä niiden tarvitse olla peräkkäin. | ||||
| A \key{map} is a generalized array | ||||
| that consists of key-value-pairs. | ||||
| While the keys in a regular array are always | ||||
| the successive integers $0,1,\ldots,n-1$, | ||||
| where $n$ is the size of the array, | ||||
| the keys in a map can be of any data type and | ||||
| they don't have to be successive values. | ||||
| 
 | ||||
| C++ sisältää kaksi toteutusta hakemistolle | ||||
| samaan tapaan kuin joukolle. | ||||
| Rakenne | ||||
| \texttt{map} perustuu | ||||
| tasapainoiseen binääripuuhun ja sen | ||||
| alkioiden käsittely vie aikaa $O(\log n)$, | ||||
| kun taas rakenne | ||||
| \texttt{unordered\_map} perustuu | ||||
| hajautustauluun ja sen alkioiden | ||||
| käsittely vie keskimäärin aikaa $O(1)$. | ||||
| C++ contains two map implementations that | ||||
| correspond to the set implementations: | ||||
| the structure | ||||
| \texttt{map} is based on a balanced | ||||
| binary tree and accessing an element | ||||
| takes $O(\log n)$ time, | ||||
| while the structure | ||||
| \texttt{unordered\_map} uses a hash map | ||||
| and accessing an element takes $O(1)$ time on average. | ||||
| 
 | ||||
| Seuraava koodi toteuttaa hakemiston, | ||||
| jossa avaimet ovat merkkijonoja ja | ||||
| arvot ovat kokonaislukuja: | ||||
| The following code creates a map | ||||
| where the keys are strings and the values are integers: | ||||
| 
 | ||||
| \begin{lstlisting} | ||||
| map<string,int> m; | ||||
| m["apina"] = 4; | ||||
| m["banaani"] = 3; | ||||
| m["cembalo"] = 9; | ||||
| cout << m["banaani"] << "\n"; // 3 | ||||
| m["monkey"] = 4; | ||||
| m["banana"] = 3; | ||||
| m["harpsichord"] = 9; | ||||
| cout << m["banana"] << "\n"; // 3 | ||||
| \end{lstlisting} | ||||
| 
 | ||||
| Jos hakemistosta hakee avainta, | ||||
| jota ei ole siinä, | ||||
| avain lisätään hakemistoon | ||||
| automaattisesti oletusarvolla. | ||||
| Esimerkiksi seuraavassa koodissa | ||||
| hakemistoon ilmestyy avain ''aybabtu'', | ||||
| jonka arvona on 0: | ||||
| If a value of a key is requested | ||||
| but the map doesn't contain it, | ||||
| the key is automatically added to the map with | ||||
| a default value. | ||||
| For example, in the following code, | ||||
| the key ''aybabtu'' with value 0 | ||||
| is added to the map. | ||||
| 
 | ||||
| \begin{lstlisting} | ||||
| map<string,int> m; | ||||
| cout << m["aybabtu"] << "\n"; // 0 | ||||
| \end{lstlisting} | ||||
| Funktiolla \texttt{count} voi | ||||
| tutkia, esiintyykö avain hakemistossa: | ||||
| The function \texttt{count} determines | ||||
| if a key exists in the map: | ||||
| \begin{lstlisting} | ||||
| if (m.count("aybabtu")) { | ||||
|     cout << "avain on hakemistossa"; | ||||
|     cout << "key exists in the map"; | ||||
| } | ||||
| \end{lstlisting} | ||||
| Seuraava koodi listaa hakemiston | ||||
| kaikki avaimet ja arvot: | ||||
| The following code prints all keys and values | ||||
| in the map: | ||||
| \begin{lstlisting} | ||||
| for (auto x : m) { | ||||
|     cout << x.first << " " << x.second << "\n"; | ||||
| } | ||||
| \end{lstlisting} | ||||
| 
 | ||||
| \section{Iteraattorit ja välit} | ||||
| \section{Iterators and ranges} | ||||
| 
 | ||||
| \index{iteraattori@iteraattori} | ||||
| \index{iterator} | ||||
| 
 | ||||
| Monet C++:n standardikirjaston funktiot | ||||
| käsittelevät tietorakenteiden iteraattoreita | ||||
| ja niiden määrittelemiä välejä. | ||||
| \key{Iteraattori} on muuttuja, | ||||
| joka osoittaa tiettyyn tietorakenteen alkioon. | ||||
| Many functions in the C++ standard library | ||||
| are given iterators to data structures, | ||||
| and iterators often correspond to ranges. | ||||
| An \key{iterator} is a variable that points | ||||
| to an element in a data structure. | ||||
| 
 | ||||
| Usein tarvittavat iteraattorit ovat \texttt{begin} | ||||
| ja \texttt{end}, jotka rajaavat välin, | ||||
| joka sisältää kaikki tietorakenteen alkiot. | ||||
| Iteraattori \texttt{begin} osoittaa | ||||
| tietorakenteen ensimmäiseen alkioon, | ||||
| kun taas iteraattori \texttt{end} osoittaa | ||||
| tietorakenteen viimeisen alkion jälkeiseen kohtaan. | ||||
| Tilanne on siis tällainen: | ||||
| Often used iterators are \texttt{begin} | ||||
| and \texttt{end} that define a range that contains | ||||
| all elements in a data structure. | ||||
| The iterator \texttt{begin} points to | ||||
| the first element in the data structure, | ||||
| and the iterator \texttt{end} points to | ||||
| the position \emph{after} the last element. | ||||
| The situation looks as follows: | ||||
| 
 | ||||
| \begin{center} | ||||
| \begin{tabular}{llllllllll} | ||||
|  | @ -342,23 +339,24 @@ Tilanne on siis tällainen: | |||
| \end{tabular} | ||||
| \end{center} | ||||
| 
 | ||||
| Huomaa epäsymmetria iteraattoreissa: | ||||
| \texttt{s.begin()} osoittaa tietorakenteen alkioon, | ||||
| kun taas \texttt{s.end()} osoittaa tietorakenteen ulkopuolelle. | ||||
| Iteraattoreiden rajaama joukon väli on siis \emph{puoliavoin}. | ||||
| Note the asymmetry in the iterators: | ||||
| \texttt{s.begin()} points to an element in the data structure, | ||||
| while \texttt{s.end()} points outside the data structure. | ||||
| Thus, the range defined by the iterators is \emph{half-open}. | ||||
| 
 | ||||
| \subsubsection{Välien käsittely} | ||||
| \subsubsection{Handling ranges} | ||||
| 
 | ||||
| Iteraattoreita tarvitsee | ||||
| C++:n standardikirjaston funktioissa, jotka käsittelevät | ||||
| tietorakenteen välejä. | ||||
| Yleensä halutaan käsitellä tietorakenteiden kaikkia | ||||
| alkioita, jolloin funktiolle annetaan | ||||
| iteraattorit \texttt{begin} ja \texttt{end}. | ||||
| Iterators are used in C++ standard library functions | ||||
| that work with ranges of data structures. | ||||
| Usually, we want to process all elements in a | ||||
| data structure, so the iterators | ||||
| \texttt{begin} and \texttt{end} are given for the function. | ||||
| 
 | ||||
| Esimerkiksi seuraava koodi järjestää vektorin funktiolla \texttt{sort}, | ||||
| kääntää sitten alkioiden järjestyksen funktiolla \texttt{reverse} | ||||
| ja sekoittaa lopuksi alkioiden järjestyksen funktiolla \texttt{random\_shuffle}. | ||||
| For example, the following code sorts a vector | ||||
| using the function \texttt{sort}, | ||||
| then reverses the order of the elements using the function | ||||
| \texttt{reverse}, and finally shuffles the order of | ||||
| the elements using the function \texttt{random\_shuffle}. | ||||
| 
 | ||||
| \index{sort@\texttt{sort}} | ||||
| \index{reverse@\texttt{reverse}} | ||||
|  | @ -370,89 +368,84 @@ reverse(v.begin(), v.end()); | |||
| random_shuffle(v.begin(), v.end()); | ||||
| \end{lstlisting} | ||||
| 
 | ||||
| Samoja funktioita voi myös käyttää tavallisen taulukon | ||||
| yhteydessä, jolloin iteraattorin sijasta annetaan | ||||
| osoitin taulukkoon: | ||||
| These functions can also be used with a regular array. | ||||
| In this case, the functions are given pointers to the array | ||||
| instead of iterators: | ||||
| 
 | ||||
| \newpage | ||||
| \begin{lstlisting} | ||||
| sort(t, t+n); | ||||
| reverse(t, t+n); | ||||
| random_shuffle(t, t+n); | ||||
| \end{lstlisting} | ||||
| 
 | ||||
| \subsubsection{Joukon iteraattorit} | ||||
| \subsubsection{Set iterators} | ||||
| 
 | ||||
| Iteraattoreita tarvitsee usein joukon | ||||
| alkioiden käsittelyssä. | ||||
| Seuraava koodi määrittelee iteraattorin | ||||
| \texttt{it}, joka osoittaa joukon \texttt{s} alkuun: | ||||
| Iterators are often used when accessing | ||||
| elements in a set. | ||||
| The following code creates an iterator | ||||
| \texttt{it} that points to the first element in the set: | ||||
| \begin{lstlisting} | ||||
| set<int>::iterator it = s.begin(); | ||||
| \end{lstlisting} | ||||
| Koodin voi kirjoittaa myös lyhyemmin näin: | ||||
| A shorter way to write the code is as follows: | ||||
| \begin{lstlisting} | ||||
| auto it = s.begin(); | ||||
| \end{lstlisting} | ||||
| Iteraattoria vastaavaan joukon alkioon | ||||
| pääsee käsiksi \texttt{*}-merkinnällä. | ||||
| Esimerkiksi seuraava koodi tulostaa | ||||
| joukon ensimmäisen alkion: | ||||
| The element to which an iterator points | ||||
| can be accessed through the \texttt{*} symbol. | ||||
| For example, the following code prints | ||||
| the first element in the set: | ||||
| 
 | ||||
| \begin{lstlisting} | ||||
| auto it = s.begin(); | ||||
| cout << *it << "\n"; | ||||
| \end{lstlisting} | ||||
| 
 | ||||
| Iteraattoria pystyy liikuttamaan | ||||
| operaatioilla \texttt{++} (eteenpäin) | ||||
| ja \texttt{---} (taaksepäin). | ||||
| Tällöin iteraattori siirtyy seuraavaan | ||||
| tai edelliseen alkioon joukossa. | ||||
| 
 | ||||
| Seuraava koodi tulostaa joukon kaikki alkiot: | ||||
| Iterators can be moved using operators | ||||
| \texttt{++} (forward) and \texttt{---} (backward), | ||||
| meaning that the iterator moves to the next | ||||
| or previous element in the set. | ||||
| 
 | ||||
| The following code prints all elements in the set: | ||||
| \begin{lstlisting} | ||||
| for (auto it = s.begin(); it != s.end(); it++) { | ||||
|     cout << *it << "\n"; | ||||
| } | ||||
| \end{lstlisting} | ||||
| Seuraava koodi taas tulostaa joukon | ||||
| viimeisen alkion: | ||||
| 
 | ||||
| The following code prints the last element in the set: | ||||
| \begin{lstlisting} | ||||
| auto it = s.end(); | ||||
| it--; | ||||
| cout << *it << "\n"; | ||||
| \end{lstlisting} | ||||
| % Iteraattoria täytyi liikuttaa askel taaksepäin, | ||||
| % koska se osoitti aluksi joukon viimeisen | ||||
| % alkion jälkeiseen kohtaan. | ||||
| 
 | ||||
| Funktio $\texttt{find}(x)$ palauttaa iteraattorin | ||||
| joukon alkioon, jonka arvo on $x$. | ||||
| Poikkeuksena jos alkiota $x$ ei esiinny joukossa, | ||||
| iteraattoriksi tulee \texttt{end}. | ||||
| The function $\texttt{find}(x)$ returns an iterator | ||||
| that points to an element whose value is $x$. | ||||
| However, if the set doesn't contain $x$, | ||||
| the iterator will be \texttt{end}. | ||||
| 
 | ||||
| \begin{lstlisting} | ||||
| auto it = s.find(x); | ||||
| if (it == s.end()) cout << "x puuttuu joukosta"; | ||||
| if (it == s.end()) cout << "x is missing"; | ||||
| \end{lstlisting} | ||||
| 
 | ||||
| Funktio $\texttt{lower\_bound}(x)$ palauttaa | ||||
| iteraattorin joukon pienimpään alkioon, | ||||
| joka on ainakin yhtä suuri kuin $x$. | ||||
| Vastaavasti $\texttt{upper\_bound}(x)$ palauttaa | ||||
| iteraattorin pienimpään alkioon, | ||||
| joka on suurempi kuin $x$. | ||||
| Jos tällaisia alkioita ei ole joukossa, | ||||
| funktiot palauttavat arvon \texttt{end}. | ||||
| Näitä funktioita ei voi käyttää | ||||
| \texttt{unordered\_set}-rakenteessa, | ||||
| joka ei pidä yllä alkioiden järjestystä. | ||||
| The function $\texttt{lower\_bound}(x)$ returns | ||||
| an iterator to the smallest element in the set | ||||
| whose value is at least $x$. | ||||
| Correspondingly,  | ||||
| the function $\texttt{upper\_bound}(x)$ | ||||
| returns an iterator to the smallest element | ||||
| in the set whose value is larger than $x$. | ||||
| If such elements do not exist, | ||||
| the return value of the functions will be \texttt{end}. | ||||
| These functions are not supported by the | ||||
| \texttt{unordered\_set} structure that | ||||
| doesn't maintain the order of the elements. | ||||
| 
 | ||||
| \begin{samepage} | ||||
| Esimerkiksi seuraava koodi etsii joukosta | ||||
| alkion, joka on lähinnä lukua $x$: | ||||
| For example, the following code finds the element | ||||
| nearest to $x$: | ||||
| 
 | ||||
| \begin{lstlisting} | ||||
| auto a = s.lower_bound(x); | ||||
|  | @ -470,20 +463,19 @@ if (a == s.begin() && a == s.end()) { | |||
| } | ||||
| \end{lstlisting} | ||||
| 
 | ||||
| Koodi käy läpi mahdolliset tapaukset | ||||
| iteraattorin \texttt{a} avulla. | ||||
| Iteraattori | ||||
| osoittaa aluksi pienimpään alkioon, | ||||
| joka on ainakin yhtä suuri kuin $x$. | ||||
| Jos \texttt{a} on samaan aikaan \texttt{begin} | ||||
| ja \texttt{end}, joukko on tyhjä. | ||||
| Muuten jos \texttt{a} on \texttt{begin}, | ||||
| sen osoittama alkio on $x$:ää lähin alkio. | ||||
| Jos taas \texttt{a} on \texttt{end}, | ||||
| $x$:ää lähin alkio on joukon viimeinen alkio. | ||||
| Jos mikään edellisistä tapauksista ei päde, | ||||
| niin $x$:ää lähin alkio | ||||
| on joko $a$:n osoittama alkio tai sitä edellinen alkio. | ||||
| The code goes through all possible cases | ||||
| using the iterator \texttt{a}. | ||||
| First, the iterator points to the smallest | ||||
| element whose value is at least $x$. | ||||
| If \texttt{a} is both \texttt{begin} | ||||
| and \texttt{end} at the same time, the set is empty. | ||||
| If \texttt{a} equals \texttt{begin}, | ||||
| the corresponding element is nearest to $x$. | ||||
| If \texttt{a} equals \texttt{end}, | ||||
| the last element in the set is nearest to $x$. | ||||
| If none of the previous cases is true, | ||||
| the element nearest to $x$ is either the | ||||
| element that corresponds to $a$ or the previous element. | ||||
| \end{samepage} | ||||
| 
 | ||||
| \section{Muita tietorakenteita} | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue