Files
PPC/Containery (vector, list, map).md

5.9 KiB

Vector

  • geegs for geegs - to jsem prakticky vykradl
  • vlastně třída, která je implementací dynamického pole
  • Proč se to jmenuje vector? Protože to autor standardní knihovny (Alex Stepanov) prostě nešikovně pojmenoval

"One could argue that valarray should have been called vector because it is a traditional mathematical vector and that vector should have been called array. However, this is not the way the terminology evolved." - Bjarne Stroustrup (autor jazyka)

Vektory mají svoje funkce, které umožňují základní operace s polem typu: přidání prvku na začátek a na konec, přidání prvku na n-tou pozici, přepsaní a přístup, mazání prvků...

Inicializace

Syntax: vector<typ_polezek> v1; Příklad inicializace:

#include <iostream>
#include <vector>

int main(void)
{
	vector<int> v1; //neinicializovaný vektor
	vector<int> v2 = {1, 2, 3}; //vekor s prvky 1 2 3
	vectro<int> v3(8, 42); //vektor o 8 prvcích o hodnotě 42

	vector<char> v4 = {'f', 's', 'o', 'c', 'i', 'e', 't', 'y'};
	vector<string> v5 =
	{
		"Do not go gentle into that good night,",
		"Old age should burn and rave at close of day;",
		"Rage, rage against the dying of the light."
	};
	vector<nejaka_trida> v6;
	
return 0;
}

begin(), end(), empty()

  • begin() a end() jsou to funkce vektoru, které vrací iterátory na první a poslední hodnotu.
  • Když je vector prázdny platí: v.begin() == v.end(). To můžeme taky poznat pomocí funkce v.end().
  • v.end() vždy ukazuje na prázdnou hodnotu za posledním prvkem vektoru, kam lze bezstarostně zapisovat další prvek, když třeba.

Přidání prvku

  • máme funkce v.push_back() a v.insert()
  • v.push_back(hodnota) přidá hodnotu na konec vektoru
  • Funkce v.insert() přidává hodnotu/hodnoty na n-tý prvek a má několik různých možností zápisu:
#include <iostream>
#include <vector>
using namespace std;

int main(void)
{
	//prazdny koncert
    vector<string> koncert;
    //pridani prvniho prvku na konec pomoci push_back
	koncert.push_back("prvni pisnicka");
	//pridani prvku na posledni pozici
	koncert.insert(koncert.end(), "lidi jdou pít do klubu")
	//pridani 3 prvku na 1. pozici (tedy prvek na posledni pozici se posune o 3)
	koncert.insert(koncert.begin() + 1, 3, "opravdu posledni pisnicka");
	
	for (string udalost : koncert)
	{
		cout << udalost << endl;
	}
	
return 0;
}

//VYPIS:
//prvni pisnicka
//opravdu posledni pisnicka
//opravdu posledni pisnicka
//opravdu posledni pisnicka
//lidi jdou pít do klubu

Možnosti insert:

vector<int> a;
vector<int> b;
a.insert(pozice a, hodnota);
a.insert(pozice a, pocet_prvku, hodnota);
a.insert(pozice a, poc_poz_jineho_vek, konc_pozice_jin_vek);

//přepíše vektor b na začátek vektoru a
a.insert(a.begin(), b.begin(), b.(end))

Přístup k prvkům a změna

  • v podstatě mám 2 možnosti a to v[i] nebo v.at(i)
  • Fungují stejně akorát v.at() vyhodí výjimku při pokusu přistupovat mimo pole a je nepatrně pomalejší
  • výjimka je std::out_of_range
#include <iosteam>
#include <vector>
using namespace std;

int main(void)
{
	vector<string> v = {"Ronald", "Artiom", "Chang", "Waldo"};
	cout << v[0] << endl;
	cout << v.at(3) << endl;
	//cout << v.at(4) << endl; //vyhodí výjimku out of range
	
	//zmena jmen
	v[1] = "Mercedes";
	v.at(2) = "Anička";
	//v.at(7) = "Pavla"; //vyhodi vyjimku
	
	return 0;
}

size a využití

  • v.size() vrací počet prvků
#include <iosteam>
#include <vector>
using namespace std;

int main(void)
{
	vector<string> v = {"Ronald", "Artiom", "Chang", "Waldo"};
	cout << v.size() << endl; //vypíše 4
	
	for (int i = 0; i < v.size(); i++)
    {cout << v[i] << " ";} //vypíše všechny jména vedle sebe
    return 0;
}

Mázaní prvků

  • mám 2 možnosti a to v.pop_back() a v.erase()
  • v.pop_back() vymaže poslední prvek z vektoru
  • v.erase() vymaže n-tý prvek a posune celý vektor. Potřebuje knihovnu <algorithm>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    vector<char> v = {1, 2, 8, 4, 0};

  	v.pop_back(); //vymaže 0
  	v.erase(v.begin()); // vymaže 1
  	v.erase(find(v.begin(), v.end(), 8)); //najde a vymaže 8

  	
  	for (int i = 0; i < v.size(); i++) {
        cout << v[i] << " ";
    } //zbyde 2,4
    return 0;
}

List

V podstatě se ovládá jako vektor, akorát má odlišné vlastnosti rychlosti přístupu k prvkům. V listu je pomalejší vyhledávat prvek (najít prvek na n-té pozici -> O(n)). Mazání a přidávání prvku bývá ale jednodušší (pokud nejprve nehledáme pozici -> O(1)).

List jako knihovnu přidáme pomocí #include <list>

Inicializace

#include <list>

int main(void)
{
	list<string> cars; //prazdný list stringů
	list<int> numbers; //prázdný list integerů
	list<string> names = {"Perec","Maxim","Sasha"}; //list se jmény
}

Přístup

Pro přístup můžu využít funkce jako l.front() nebo l.back(). Popřípadě list[]

#include <iostream>
#include <list>

int main(void)
{
	list<string> matematika = {"Matalyza1", "Lingebra", "Matalyza2", "Komplexni analyza"};
	std::cout << cvut.front() << std::endl;
	std::cout << cvut.back() << std::endl;
	std::cout << cvut[3] << std::endl;
	
	//vypise
	//FEL
	//FBmi
	//FA
	
	cvut.front() = "Lingebra";
	cvut.back() = "Lingebra";
	cvut[2] = "Lingebra";
}

memisek

DOPLN CO SE STANE KDYZ ACCESS MIMO INDEX!

Pomocné funkce

Krom funkcí

Projetí listu pomocí for loop:

list<string> veta = {"Co", "je", "moje", "to", "je", "tvoje"};  
  
for (int i = 0; i < cars.size(); i++) {  
  cout << cars[i] << "\n";  
}

Map

Unordered_map