STL C++: Unterschied zwischen den Versionen
Zur Navigation springen
Zur Suche springen
(→vector) |
|||
(25 dazwischenliegende Versionen von 3 Benutzern werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
= Links = | = Links = | ||
* [[C-plus-plus]] | * [[C-plus-plus]] | ||
* https://cplusplus.com/reference/stl/ | |||
= Container = | = Container = | ||
Zeile 95: | Zeile 96: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== | == vector == | ||
* | |||
<syntaxhighlight lang="c++"> | <syntaxhighlight lang="c++"> | ||
std::vector<int> vec = {1,2,3,4,5}; | std::vector<int> vec = {1,2,3,4,5}; | ||
Zeile 102: | Zeile 104: | ||
std::cout << ' ' << *rit; | std::cout << ' ' << *rit; | ||
std::cout << '\n'; | std::cout << '\n'; | ||
# Einfügen: | |||
people.insert(people.begin() + index, temp); | |||
# Löschen: | |||
people.erase(people.begin() + 4, people.end() - 1); | |||
# Anhängen | |||
std::vector<int> vec2 = {99, 100}; | |||
vec.insert(vec.end(), vec2.begin(), vec2.end()); | |||
auto it = find (vec2.begin(), vec2.end(), 99); | |||
assertTrue(it != vec2.end()); | |||
</syntaxhighlight> | |||
== deque == | |||
* Aufwand einfügen vorn oder hinten ist gleich. | |||
* Funktionalität wie Vector | |||
== list == | |||
Doppelt verkettete Liste: Einfügen an jeder Stelle mit konstantem Aufwand. | |||
== forward_list == | |||
Einfach verkettete Liste: Einfügen an jeder Stelle mit konstantem Aufwand. | |||
== stack == | |||
* Last in first out | |||
* Implementiert mit vector, deque und list | |||
Funktionen: | |||
* empty() | |||
* size() | |||
* top() | |||
* push() | |||
* emplace | |||
* void pop() | |||
* swap() | |||
== Set == | |||
Jedes Element nur einmal. | |||
Operationen: | |||
* insert() erase() | |||
* swap() | |||
* clear() | |||
* emplace(): construct and insert | |||
* find() | |||
* count() | |||
* lower_bound() upper_bound equal_range() | |||
<syntaxhighlight lang="c++"> | |||
#include <set> | |||
std::set<int> myset; | |||
std::set<int>::iterator it; | |||
// set some initial values: | |||
for (int i=1; i<=5; i++) | |||
myset.insert(i*10); | |||
it=myset.find(20); | |||
if (it != myset.end()) | |||
myset.erase (it); | |||
myset.erase (myset.find(40)); | |||
</syntaxhighlight> | |||
== Map == | |||
Assoziatives Array, jeder Schlüssel nur einmal. | |||
Operationen: | |||
* T& [key]: Erstellt Eintrag, wenn nicht vorhanden! | |||
* T at(K key) Speichern von Werten: map.at(key) = value; Analog zu map[key] = value; | |||
* iterator find(K key) https://cplusplus.com/reference/map/map/find/ | |||
* iterator lower_bound(K key) Iterator zeigt auf größtes Element <= key | |||
* iterator upper_bound(K key) Iterator zeigt auf kleinstes Element >= key | |||
<syntaxhighlight lang="c++"> | |||
#include <map> | |||
static std::map<int, int> s_map = { {1, 44}, {3, 99} }; | |||
std::map<string, int> ranking; | |||
auto it = ranking.find("joe"); | |||
if (it != ranking.end()){ | |||
auto rankingValue = it->second; | |||
} | |||
std::map<int, float>m; | |||
for (const auto& [key, value] : m){ | |||
doIt(key, value); | |||
} | |||
for (auto pair : m){ | |||
auto key = pair->first; | |||
} | |||
</syntaxhighlight> | |||
Konstruktoren: | |||
* Es kann die Vergleichsfunktion als Parameter mitgegeben werden. | |||
<syntaxhighlight lang="c++"> | |||
const std::map<std::string, int> init { | |||
{"this", 100}, | |||
{"can", 100}, | |||
{"be", 100}, | |||
{"const", 100}, | |||
}; | |||
auto cmpLambda = [&mag](const Point &lhs, const Point &rhs) { | |||
return mag[lhs] < mag[rhs]; | |||
}; | |||
// You could also use a lambda that is not dependent on local variables, like this: | |||
// auto cmpLambda = [](const Point &lhs, const Point &rhs) { return lhs.y < rhs.y; }; | |||
std::map<Point, double, decltype(cmpLambda)> magy(cmpLambda); | |||
</syntaxhighlight> | |||
== Algorithmen == | |||
Arbeiten auf Containern. | |||
=== Find === | |||
* find() findet Element | |||
* find_if() findet mittels Prädikatsfunktion (Funktion oder Lambda-Funktion). | |||
<syntaxhighlight lang="c++"> | |||
#include <stdio.h> | |||
#include <string> | |||
#include <iterator> | |||
#include <algorithm> | |||
#include <vector> | |||
bool isEven (int i) { return i%2==0; } | |||
int main () { | |||
int myints[] = {32,71,12,45,26,80,53,33}; | |||
std::vector<int> vec (myints, myints+8); // 32 71 12 45 26 80 53 33 | |||
if (std::find(vec.begin(), vec.end(), 99) != vec.end()){ | |||
printf("99 is here"); | |||
} | |||
auto it2 = std::find_if (vec.begin(), vec.end(), isEven); | |||
bool even = it2 != vec.end(); | |||
printf("first even: %d", ! even ? 0 : *it2); | |||
} | |||
</syntaxhighlight> | |||
=== Sort === | |||
* Entweder globale Funktion (oder Lambafunktion) als Parameter. Implementiert "<" Operator. | |||
* oder eine Klasse mit Operator ()(K i, K j) als Parameter. Implementiert "<" Operator. | |||
<syntaxhighlight lang="c++"> | |||
#include <iterator> | |||
#include <algorithm> | |||
#include <vector> | |||
bool compareInt (int i,int j) { return (i<j); } | |||
struct Data { | |||
bool operator() (int i,int j) { return (i<j);} | |||
} data; | |||
int main () { | |||
int myints[] = {32,71,12,45,26,80,53,33}; | |||
std::vector<int> vec (myints, myints+8); // 32 71 12 45 26 80 53 33 | |||
// using default comparison (operator <): | |||
std::sort (vec.begin(), vec.begin()+4); //(12 32 45 71)26 80 53 33 | |||
// using function as comp | |||
std::sort (vec.begin()+4, vec.end(), compareInt); // 12 32 45 71(26 33 53 80) | |||
// using object as comp | |||
std::sort (vec.begin(), vec.end(), data); //(12 26 32 33 45 53 71 80) | |||
} | |||
</syntaxhighlight> | |||
=== copy_if === | |||
<syntaxhighlight lang="c++"> | |||
#include <algorithm> // std::copy_if, std::distance | |||
#include <vector> // std::vector | |||
int main () { | |||
std::vector<int> foo = {25,15,5,-5,-15}; | |||
std::vector<int> bar (foo.size()); | |||
// copy only positive numbers: | |||
auto it = std::copy_if (foo.begin(), foo.end(), bar.begin(), [](int i){return !(i<0);} ); | |||
bar.resize(std::distance(bar.begin(),it)); // shrink container to new size | |||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
== RegExpr == | == RegExpr == | ||
* https://en.cppreference.com/w/cpp/regex/regex_search | |||
* https://en.cppreference.com/w/cpp/regex/match_results | |||
* bool regex_match(subject, regexpr) Treffer muss am Anfang und am Ende des Subjekts sein | |||
* bool regex_search(subject, regexpr) Treffer kann in Substring von Subjekt sein | |||
* regex_replace(subject, regexpr, replacement) Erzeugt neuen String mit Ersetzungen | |||
<syntaxhighlight lang="c++"> | <syntaxhighlight lang="c++"> | ||
#include <string> | |||
#include <regex> | |||
#include <iostream> | |||
int main () | |||
{ | |||
std::regex rgx("WEBMSG #([a-zA-Z0-9]+) :(.*)", std::regex_constants::icase); | |||
std::cmatch matches; | |||
const char* line1 = "WEBMSG #anExample"; | |||
if(std::regex_search(line1, matches, rgx)) { | |||
std::cout << "Match found\n"; | |||
for (size_t i = 1; i= < matches.size(); ++i) { | |||
std::cout << i << ": '" << matches[i].str() << "'\n"; | |||
} | |||
} else { | |||
std::cout << "Match not found\n"; | |||
} | |||
} | |||
std::string line2(line1); | |||
std::smatch matches; | |||
if(std::regex_search(line2, matches, rgx)) { | |||
// ... | |||
} | |||
if (std::regex_match ("subject", std::regex("(sub)(.*)") )) | |||
std::cout << "string literal matched\n"; | |||
std::string s ("there is a subsequence in the string\n"); | |||
std::regex e ("\\b(sub)([^ ]*)"); // matches words beginning by "sub" | |||
// using string/c-string (3) version: | |||
std::cout << std::regex_replace (s,e,"sub-$2"); | |||
// using range/c-string (6) version: | |||
std::string result; | |||
std::regex_replace (std::back_inserter(result), s.begin(), s.end(), e, "$2"); | |||
std::cout << result; | |||
// with flags: | |||
std::cout << std::regex_replace (s,e,"$1 and $2",std::regex_constants::format_no_copy); | |||
std::cout << std::endl; | |||
// Gruppen: | |||
std::cmatch matches; | |||
const char* string = "statistic: lines: 20 chars: 30"; | |||
std::regex rgx("(\\d+).*(\\d+)"); | |||
if (std::regex_search(string, matches, rgx)) { | |||
printf("group count: %ld\n", matches.size()); | |||
printf("Hit 1: pos: %ld %length: %ld hit: %s\n", matches.position(1), matches.length(1), matches.str(1).c_str()); | |||
printf("Hit 2: pos: %ld %length: %ld hit: %s\n", matches.position(2), matches.length(2), matches.str(2).c_str()); | |||
} | |||
return 0; | |||
} | |||
</syntaxhighlight> | </syntaxhighlight> |
Aktuelle Version vom 8. November 2024, 17:02 Uhr
Links[Bearbeiten]
Container[Bearbeiten]
Beispiele: vector, string
Zugriff/Manipulation
- size_t length() Aktuelle Länge
- size_t capacity() Liefert aktuell Puffergröße
- void resize(size_t newLen, [char cc = '\0']) Setzt Länge durch Kürzen oder Auffüllen mit cc
- reserve(size_t newSize): Setzt Kapazität
- clear() Kürzt auf 0
- bool empty() Test auf Leerstring
- T & back() Letztes Element
- T & front() erstes Element
- append(data)
- push_back(T cc) Element anfügen
- T pop_back() Letztes Element entfernen und zurückgeben
- insert(size_t pos, data)
- emplace(size_t pos, T item) ein Element einfügen
- emplace_back(T item) ein Element anhängen
- iterator erase(size_t pos, size_t len) Löschen
- iterator erase(iterator begin, iterator end) Löschen
Finden und Ersetzen
- replace(pos, len, data)
- size_t find(data) Substring finden
- size_t rfind(data) Von hinten Substring finden
- find_first_of(T item)
- find_last_of(T item)
Iteratoren:
- begin
- end
- rbegin Vom Ende her
- rend
- cbegin Ein const-Iterator
- cend
- crbegin
- crend
#include <vector>
std::vector v;
for (auto rit=v.rbegin(); rit!=v.rend(); ++rit){
std::cout << *rit;
}
for (auto it=v.begin(); it!=v.end(); ++it)[
std::cout << *it;
}
for ( auto it=v.cbegin(); it!=v.cend(); ++it){
std::cout << *it;
}
String[Bearbeiten]
Konstruktoren:
- string() https://cplusplus.com/reference/string/string/string/
- string(data)
- string(int count, char c)
Zugriff/Manipulation (außer Standard von Containern):
- int compare(data) Vergleich: <0 0 >0 https://cplusplus.com/reference/string/string/compare/
- string substr(size_t pos, size_t len) Teilstring erstellen
- char& at(int position) Liefert Zeichen von Position
- char& back() Letztes Zeichen
- char& front() erstes Zeichen
Finden und Ersetzen
- replace(pos, len, data) https://cplusplus.com/reference/string/string/replace/
- size_t find(data) Substring finden https://cplusplus.com/reference/string/string/find/
- size_t rfind(data) Von hinten Substring finden
- find_first_of(char cc)
- find_last_of(char cc)
Konvertierung
- int stoi() Wandlung in int
- const char* c_str() C-String
- string to_string(NUMERIC val) int, long, ... long double in String wandeln https://cplusplus.com/reference/string/to_string/
#include <string>
std::string s;
for (auto rit=str.rbegin(); rit!=str.rend(); ++rit){
std::cout << *rit;
}
for (auto it=str.begin(); it!=str.end(); ++it)[
std::cout << *it;
}
for ( auto it=str.cbegin(); it!=str.cend(); ++it){
std::cout << *it;
}
vector[Bearbeiten]
std::vector<int> vec = {1,2,3,4,5};
std::cout << "vec backwards:";
for (auto rit = vec.crbegin(); rit != vec.crend(); ++rit)
std::cout << ' ' << *rit;
std::cout << '\n';
# Einfügen:
people.insert(people.begin() + index, temp);
# Löschen:
people.erase(people.begin() + 4, people.end() - 1);
# Anhängen
std::vector<int> vec2 = {99, 100};
vec.insert(vec.end(), vec2.begin(), vec2.end());
auto it = find (vec2.begin(), vec2.end(), 99);
assertTrue(it != vec2.end());
deque[Bearbeiten]
- Aufwand einfügen vorn oder hinten ist gleich.
- Funktionalität wie Vector
list[Bearbeiten]
Doppelt verkettete Liste: Einfügen an jeder Stelle mit konstantem Aufwand.
forward_list[Bearbeiten]
Einfach verkettete Liste: Einfügen an jeder Stelle mit konstantem Aufwand.
stack[Bearbeiten]
- Last in first out
- Implementiert mit vector, deque und list
Funktionen:
- empty()
- size()
- top()
- push()
- emplace
- void pop()
- swap()
Set[Bearbeiten]
Jedes Element nur einmal.
Operationen:
- insert() erase()
- swap()
- clear()
- emplace(): construct and insert
- find()
- count()
- lower_bound() upper_bound equal_range()
#include <set>
std::set<int> myset;
std::set<int>::iterator it;
// set some initial values:
for (int i=1; i<=5; i++)
myset.insert(i*10);
it=myset.find(20);
if (it != myset.end())
myset.erase (it);
myset.erase (myset.find(40));
Map[Bearbeiten]
Assoziatives Array, jeder Schlüssel nur einmal.
Operationen:
- T& [key]: Erstellt Eintrag, wenn nicht vorhanden!
- T at(K key) Speichern von Werten: map.at(key) = value; Analog zu map[key] = value;
- iterator find(K key) https://cplusplus.com/reference/map/map/find/
- iterator lower_bound(K key) Iterator zeigt auf größtes Element <= key
- iterator upper_bound(K key) Iterator zeigt auf kleinstes Element >= key
#include <map>
static std::map<int, int> s_map = { {1, 44}, {3, 99} };
std::map<string, int> ranking;
auto it = ranking.find("joe");
if (it != ranking.end()){
auto rankingValue = it->second;
}
std::map<int, float>m;
for (const auto& [key, value] : m){
doIt(key, value);
}
for (auto pair : m){
auto key = pair->first;
}
Konstruktoren:
- Es kann die Vergleichsfunktion als Parameter mitgegeben werden.
const std::map<std::string, int> init {
{"this", 100},
{"can", 100},
{"be", 100},
{"const", 100},
};
auto cmpLambda = [&mag](const Point &lhs, const Point &rhs) {
return mag[lhs] < mag[rhs];
};
// You could also use a lambda that is not dependent on local variables, like this:
// auto cmpLambda = [](const Point &lhs, const Point &rhs) { return lhs.y < rhs.y; };
std::map<Point, double, decltype(cmpLambda)> magy(cmpLambda);
Algorithmen[Bearbeiten]
Arbeiten auf Containern.
Find[Bearbeiten]
- find() findet Element
- find_if() findet mittels Prädikatsfunktion (Funktion oder Lambda-Funktion).
#include <stdio.h>
#include <string>
#include <iterator>
#include <algorithm>
#include <vector>
bool isEven (int i) { return i%2==0; }
int main () {
int myints[] = {32,71,12,45,26,80,53,33};
std::vector<int> vec (myints, myints+8); // 32 71 12 45 26 80 53 33
if (std::find(vec.begin(), vec.end(), 99) != vec.end()){
printf("99 is here");
}
auto it2 = std::find_if (vec.begin(), vec.end(), isEven);
bool even = it2 != vec.end();
printf("first even: %d", ! even ? 0 : *it2);
}
Sort[Bearbeiten]
- Entweder globale Funktion (oder Lambafunktion) als Parameter. Implementiert "<" Operator.
- oder eine Klasse mit Operator ()(K i, K j) als Parameter. Implementiert "<" Operator.
#include <iterator>
#include <algorithm>
#include <vector>
bool compareInt (int i,int j) { return (i<j); }
struct Data {
bool operator() (int i,int j) { return (i<j);}
} data;
int main () {
int myints[] = {32,71,12,45,26,80,53,33};
std::vector<int> vec (myints, myints+8); // 32 71 12 45 26 80 53 33
// using default comparison (operator <):
std::sort (vec.begin(), vec.begin()+4); //(12 32 45 71)26 80 53 33
// using function as comp
std::sort (vec.begin()+4, vec.end(), compareInt); // 12 32 45 71(26 33 53 80)
// using object as comp
std::sort (vec.begin(), vec.end(), data); //(12 26 32 33 45 53 71 80)
}
copy_if[Bearbeiten]
#include <algorithm> // std::copy_if, std::distance
#include <vector> // std::vector
int main () {
std::vector<int> foo = {25,15,5,-5,-15};
std::vector<int> bar (foo.size());
// copy only positive numbers:
auto it = std::copy_if (foo.begin(), foo.end(), bar.begin(), [](int i){return !(i<0);} );
bar.resize(std::distance(bar.begin(),it)); // shrink container to new size
}
RegExpr[Bearbeiten]
- https://en.cppreference.com/w/cpp/regex/regex_search
- https://en.cppreference.com/w/cpp/regex/match_results
- bool regex_match(subject, regexpr) Treffer muss am Anfang und am Ende des Subjekts sein
- bool regex_search(subject, regexpr) Treffer kann in Substring von Subjekt sein
- regex_replace(subject, regexpr, replacement) Erzeugt neuen String mit Ersetzungen
#include <string>
#include <regex>
#include <iostream>
int main ()
{
std::regex rgx("WEBMSG #([a-zA-Z0-9]+) :(.*)", std::regex_constants::icase);
std::cmatch matches;
const char* line1 = "WEBMSG #anExample";
if(std::regex_search(line1, matches, rgx)) {
std::cout << "Match found\n";
for (size_t i = 1; i= < matches.size(); ++i) {
std::cout << i << ": '" << matches[i].str() << "'\n";
}
} else {
std::cout << "Match not found\n";
}
}
std::string line2(line1);
std::smatch matches;
if(std::regex_search(line2, matches, rgx)) {
// ...
}
if (std::regex_match ("subject", std::regex("(sub)(.*)") ))
std::cout << "string literal matched\n";
std::string s ("there is a subsequence in the string\n");
std::regex e ("\\b(sub)([^ ]*)"); // matches words beginning by "sub"
// using string/c-string (3) version:
std::cout << std::regex_replace (s,e,"sub-$2");
// using range/c-string (6) version:
std::string result;
std::regex_replace (std::back_inserter(result), s.begin(), s.end(), e, "$2");
std::cout << result;
// with flags:
std::cout << std::regex_replace (s,e,"$1 and $2",std::regex_constants::format_no_copy);
std::cout << std::endl;
// Gruppen:
std::cmatch matches;
const char* string = "statistic: lines: 20 chars: 30";
std::regex rgx("(\\d+).*(\\d+)");
if (std::regex_search(string, matches, rgx)) {
printf("group count: %ld\n", matches.size());
printf("Hit 1: pos: %ld %length: %ld hit: %s\n", matches.position(1), matches.length(1), matches.str(1).c_str());
printf("Hit 2: pos: %ld %length: %ld hit: %s\n", matches.position(2), matches.length(2), matches.str(2).c_str());
}
return 0;
}