Add Modul 8 C++: STL, Iteratoren, Lambdas
This commit is contained in:
333
src/cpp_examples/module8_stl_cpp.cpp
Normal file
333
src/cpp_examples/module8_stl_cpp.cpp
Normal file
@@ -0,0 +1,333 @@
|
|||||||
|
// ============================================
|
||||||
|
// C++ Vergleich: Modul 8 - STL Fortgeschritten
|
||||||
|
// Iteratoren, Funktoren, Lambdas, Algorithmen
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include <list>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <numeric>
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// 1. ITERATOREN
|
||||||
|
// ============================================
|
||||||
|
void demo_iterators() {
|
||||||
|
std::cout << "=== C++: Iteratoren ===\n\n";
|
||||||
|
|
||||||
|
std::vector<int> vec = {10, 20, 30, 40, 50};
|
||||||
|
|
||||||
|
// Iterator-Typen
|
||||||
|
std::cout << "1. Verschiedene Iterator-Typen:\n";
|
||||||
|
|
||||||
|
// begin() / end() - normale Iteratoren
|
||||||
|
std::cout << " Forward: ";
|
||||||
|
for (auto it = vec.begin(); it != vec.end(); ++it) {
|
||||||
|
std::cout << *it << " ";
|
||||||
|
}
|
||||||
|
std::cout << "\n";
|
||||||
|
|
||||||
|
// rbegin() / rend() - reverse Iteratoren
|
||||||
|
std::cout << " Reverse: ";
|
||||||
|
for (auto it = vec.rbegin(); it != vec.rend(); ++it) {
|
||||||
|
std::cout << *it << " ";
|
||||||
|
}
|
||||||
|
std::cout << "\n";
|
||||||
|
|
||||||
|
// const_iterator (nur lesen)
|
||||||
|
std::cout << " Const: ";
|
||||||
|
for (std::vector<int>::const_iterator it = vec.cbegin(); it != vec.cend(); ++it) {
|
||||||
|
// *it = 100; // ERROR: Read-only!
|
||||||
|
std::cout << *it << " ";
|
||||||
|
}
|
||||||
|
std::cout << "\n\n";
|
||||||
|
|
||||||
|
// Iterator-Arithmetik (nur RandomAccess-Iteratoren)
|
||||||
|
std::cout << "2. Iterator-Arithmetik:\n";
|
||||||
|
auto it = vec.begin();
|
||||||
|
std::cout << " *it = " << *it << "\n";
|
||||||
|
std::cout << " *(it+2) = " << *(it + 2) << "\n";
|
||||||
|
std::cout << " *(end-1) = " << *(vec.end() - 1) << "\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// 2. FUNKTOREN (Function Objects)
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
// Eigener Funktor
|
||||||
|
class GreaterThan {
|
||||||
|
private:
|
||||||
|
int threshold_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit GreaterThan(int threshold) : threshold_(threshold) {}
|
||||||
|
|
||||||
|
// operator() überladen
|
||||||
|
bool operator()(int value) const {
|
||||||
|
return value > threshold_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Funktor mit Zustand
|
||||||
|
class AverageCalculator {
|
||||||
|
private:
|
||||||
|
double sum_ = 0;
|
||||||
|
int count_ = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void operator()(int value) {
|
||||||
|
sum_ += value;
|
||||||
|
count_++;
|
||||||
|
}
|
||||||
|
|
||||||
|
double average() const {
|
||||||
|
return count_ > 0 ? sum_ / count_ : 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void demo_functors() {
|
||||||
|
std::cout << "=== C++: Funktoren ===\n\n";
|
||||||
|
|
||||||
|
std::vector<int> vec = {10, 25, 5, 30, 15, 40};
|
||||||
|
|
||||||
|
// 1. Eigener Funktor
|
||||||
|
std::cout << "1. GreaterThan Funktor:\n";
|
||||||
|
GreaterThan gt20(20);
|
||||||
|
|
||||||
|
auto it = std::find_if(vec.begin(), vec.end(), gt20);
|
||||||
|
if (it != vec.end()) {
|
||||||
|
std::cout << " Erster Wert > 20: " << *it << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zählen
|
||||||
|
int count = std::count_if(vec.begin(), vec.end(), GreaterThan(15));
|
||||||
|
std::cout << " Werte > 15: " << count << "\n\n";
|
||||||
|
|
||||||
|
// 2. Funktor mit Zustand
|
||||||
|
std::cout << "2. AverageCalculator (Zustand):\n";
|
||||||
|
AverageCalculator avg;
|
||||||
|
for (int x : vec) {
|
||||||
|
avg(x); // Aufruf wie Funktion
|
||||||
|
}
|
||||||
|
std::cout << " Durchschnitt: " << avg.average() << "\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// 3. LAMBDAS (C++11)
|
||||||
|
// ============================================
|
||||||
|
void demo_lambdas() {
|
||||||
|
std::cout << "=== C++: Lambdas ===\n\n";
|
||||||
|
|
||||||
|
std::vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||||
|
|
||||||
|
// Lambda-Syntax: [capture](params) -> return_type { body }
|
||||||
|
|
||||||
|
// 1. Einfaches Lambda
|
||||||
|
std::cout << "1. Einfaches Lambda:\n";
|
||||||
|
auto square = [](int x) { return x * x; };
|
||||||
|
std::cout << " square(5) = " << square(5) << "\n\n";
|
||||||
|
|
||||||
|
// 2. Lambda in Algorithmus
|
||||||
|
std::cout << "2. Lambda in std::for_each:\n";
|
||||||
|
std::for_each(vec.begin(), vec.end(), [](int x) {
|
||||||
|
std::cout << x * x << " ";
|
||||||
|
});
|
||||||
|
std::cout << "\n\n";
|
||||||
|
|
||||||
|
// 3. Lambda mit Capture
|
||||||
|
std::cout << "3. Capture (Werte einfangen):\n";
|
||||||
|
int factor = 3;
|
||||||
|
auto multiply = [factor](int x) { return x * factor; };
|
||||||
|
std::cout << " 5 * " << factor << " = " << multiply(5) << "\n\n";
|
||||||
|
|
||||||
|
// 4. Mutable Lambda (veränderbarer Capture)
|
||||||
|
std::cout << "4. Mutable Lambda:\n";
|
||||||
|
int counter = 0;
|
||||||
|
auto increment = [counter]() mutable { return ++counter; };
|
||||||
|
std::cout << " " << increment() << " " << increment() << " " << increment() << "\n";
|
||||||
|
std::cout << " Original counter: " << counter << " (unverändert!)\n\n";
|
||||||
|
|
||||||
|
// 5. Capture by reference
|
||||||
|
std::cout << "5. Capture by Reference:\n";
|
||||||
|
int sum = 0;
|
||||||
|
std::for_each(vec.begin(), vec.end(), [&sum](int x) {
|
||||||
|
sum += x;
|
||||||
|
});
|
||||||
|
std::cout << " Summe: " << sum << "\n\n";
|
||||||
|
|
||||||
|
// 6. Generic Lambda (C++14)
|
||||||
|
std::cout << "6. Generic Lambda (auto Parameter):\n";
|
||||||
|
auto generic = [](auto x, auto y) { return x + y; };
|
||||||
|
std::cout << " int: " << generic(3, 4) << "\n";
|
||||||
|
std::cout << " double: " << generic(3.5, 2.5) << "\n";
|
||||||
|
std::cout << " string: " << generic(std::string("Hello"), std::string(" World")) << "\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// 4. STL-ALGORITHMEN
|
||||||
|
// ============================================
|
||||||
|
void demo_algorithms() {
|
||||||
|
std::cout << "=== C++: STL Algorithmen ===\n\n";
|
||||||
|
|
||||||
|
std::vector<int> vec = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3};
|
||||||
|
|
||||||
|
// 1. Sorting
|
||||||
|
std::cout << "1. Sorting:\n";
|
||||||
|
std::sort(vec.begin(), vec.end());
|
||||||
|
std::cout << " Sortiert: ";
|
||||||
|
for (int x : vec) std::cout << x << " ";
|
||||||
|
std::cout << "\n";
|
||||||
|
|
||||||
|
// Reverse sort with lambda
|
||||||
|
std::sort(vec.begin(), vec.end(), [](int a, int b) { return a > b; });
|
||||||
|
std::cout << " Absteigend: ";
|
||||||
|
for (int x : vec) std::cout << x << " ";
|
||||||
|
std::cout << "\n\n";
|
||||||
|
|
||||||
|
// 2. Searching
|
||||||
|
std::cout << "2. Searching:\n";
|
||||||
|
if (std::binary_search(vec.begin(), vec.end(), 5)) {
|
||||||
|
std::cout << " 5 gefunden!\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
auto [min_it, max_it] = std::minmax_element(vec.begin(), vec.end());
|
||||||
|
std::cout << " Min: " << *min_it << ", Max: " << *max_it << "\n\n";
|
||||||
|
|
||||||
|
// 3. Transform (map)
|
||||||
|
std::cout << "3. Transform:\n";
|
||||||
|
std::vector<int> doubled;
|
||||||
|
std::transform(vec.begin(), vec.end(), std::back_inserter(doubled),
|
||||||
|
[](int x) { return x * 2; });
|
||||||
|
std::cout << " Verdoppelt: ";
|
||||||
|
for (int x : doubled) std::cout << x << " ";
|
||||||
|
std::cout << "\n\n";
|
||||||
|
|
||||||
|
// 4. Filter (copy_if)
|
||||||
|
std::cout << "4. Filter (copy_if):\n";
|
||||||
|
std::vector<int> even;
|
||||||
|
std::copy_if(vec.begin(), vec.end(), std::back_inserter(even),
|
||||||
|
[](int x) { return x % 2 == 0; });
|
||||||
|
std::cout << " Gerade Zahlen: ";
|
||||||
|
for (int x : even) std::cout << x << " ";
|
||||||
|
std::cout << "\n\n";
|
||||||
|
|
||||||
|
// 5. Reduce (accumulate)
|
||||||
|
std::cout << "5. Accumulate:\n";
|
||||||
|
int sum = std::accumulate(vec.begin(), vec.end(), 0);
|
||||||
|
int product = std::accumulate(vec.begin(), vec.end(), 1, std::multiplies<int>());
|
||||||
|
std::cout << " Summe: " << sum << "\n";
|
||||||
|
std::cout << " Produkt: " << product << "\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// 5. RANGE-BASED FOR LOOP
|
||||||
|
// ============================================
|
||||||
|
void demo_range_based_for() {
|
||||||
|
std::cout << "=== C++: Range-based for loop ===\n\n";
|
||||||
|
|
||||||
|
std::vector<std::string> names = {"Alice", "Bob", "Charlie"};
|
||||||
|
std::map<std::string, int> scores = {{"Alice", 95}, {"Bob", 87}, {"Charlie", 92}};
|
||||||
|
|
||||||
|
// By value (Kopie)
|
||||||
|
std::cout << "1. By Value (Kopie):\n ";
|
||||||
|
for (std::string name : names) {
|
||||||
|
name += "!"; // Ändert nur Kopie
|
||||||
|
std::cout << name << " ";
|
||||||
|
}
|
||||||
|
std::cout << "\n Original: ";
|
||||||
|
for (const auto& name : names) std::cout << name << " ";
|
||||||
|
std::cout << "\n\n";
|
||||||
|
|
||||||
|
// By reference (Original ändern)
|
||||||
|
std::cout << "2. By Reference:\n ";
|
||||||
|
for (auto& name : names) {
|
||||||
|
name[0] = std::tolower(name[0]); // Ändert Original!
|
||||||
|
std::cout << name << " ";
|
||||||
|
}
|
||||||
|
std::cout << "\n\n";
|
||||||
|
|
||||||
|
// Const reference (nur lesen, effizient)
|
||||||
|
std::cout << "3. Const Reference:\n ";
|
||||||
|
for (const auto& [name, score] : scores) {
|
||||||
|
std::cout << name << ": " << score << " ";
|
||||||
|
}
|
||||||
|
std::cout << "\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// 6. FUNKTIONALE KOMPOSITION
|
||||||
|
// ============================================
|
||||||
|
void demo_functional() {
|
||||||
|
std::cout << "=== C++: Funktionale Komposition ===\n\n";
|
||||||
|
|
||||||
|
// std::function für flexiblen Funktions-Typ
|
||||||
|
std::function<int(int)> operations;
|
||||||
|
|
||||||
|
// Compose: f(g(x))
|
||||||
|
auto add10 = [](int x) { return x + 10; };
|
||||||
|
auto mul2 = [](int x) { return x * 2; };
|
||||||
|
|
||||||
|
// compose: add10(mul2(x))
|
||||||
|
auto compose = [add10, mul2](int x) {
|
||||||
|
return add10(mul2(x));
|
||||||
|
};
|
||||||
|
|
||||||
|
std::cout << "1. Komposition: add10(mul2(5)) = " << compose(5) << "\n";
|
||||||
|
// 5 * 2 = 10, 10 + 10 = 20
|
||||||
|
|
||||||
|
// Pipeline-ähnliche Verarbeitung
|
||||||
|
std::vector<int> data = {1, 2, 3, 4, 5};
|
||||||
|
|
||||||
|
auto result = data
|
||||||
|
| std::views::transform([](int x) { return x * 2; })
|
||||||
|
| std::views::filter([](int x) { return x > 4; })
|
||||||
|
| std::views::take(3);
|
||||||
|
|
||||||
|
// C++23 Ranges (falls verfügbar)
|
||||||
|
// Oder klassisch:
|
||||||
|
std::vector<int> pipeline_result;
|
||||||
|
for (int x : data) {
|
||||||
|
int doubled = x * 2;
|
||||||
|
if (doubled > 4) {
|
||||||
|
pipeline_result.push_back(doubled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "2. Pipeline Ergebnis: ";
|
||||||
|
for (int x : pipeline_result) std::cout << x << " ";
|
||||||
|
std::cout << "\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// HAUPTPROGRAMM
|
||||||
|
// ============================================
|
||||||
|
int main() {
|
||||||
|
std::cout << "=== C++ STL: Iteratoren, Lambdas, Algorithmen ===\n\n";
|
||||||
|
|
||||||
|
demo_iterators();
|
||||||
|
demo_functors();
|
||||||
|
demo_lambdas();
|
||||||
|
demo_algorithms();
|
||||||
|
demo_range_based_for();
|
||||||
|
demo_functional();
|
||||||
|
|
||||||
|
std::cout << "=== Vergleich: C vs C++ ===\n\n";
|
||||||
|
std::cout << "C:\n";
|
||||||
|
std::cout << " - Manuelle Iteration (i = 0; i < n; i++)\n";
|
||||||
|
std::cout << " - Function Pointers für Callbacks\n";
|
||||||
|
std::cout << " - Keine generische Sortierung\n";
|
||||||
|
std::cout << " - Manuelle Algorithmen-Implementierung\n\n";
|
||||||
|
|
||||||
|
std::cout << "C++:\n";
|
||||||
|
std::cout << " - Iteratoren (einheitlich für alle Container)\n";
|
||||||
|
std::cout << " - Funktoren + Lambdas (typsicher, inline-fähig)\n";
|
||||||
|
std::cout << " - 100+ generische Algorithmen\n";
|
||||||
|
std::cout << " - Range-based for (elegant)\n";
|
||||||
|
std::cout << " - std::function für flexible Callbacks\n";
|
||||||
|
std::cout << " - Algorithmen sind optimiert und getestet\n";
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user