SS 2025
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
int main() {
|
||||
int vector_size;
|
||||
std::vector<int> vec;
|
||||
|
||||
std::cout << "Bitte geben Sie die Größe des Vektors an: ";
|
||||
std::cin >> vector_size;
|
||||
|
||||
std::cout << "Geben Sie die Werte des Vektors ein:" << std::endl;
|
||||
for (int i = 0; i < vector_size; ++i) {
|
||||
int input;
|
||||
std::cin >> input;
|
||||
vec.push_back(input);
|
||||
}
|
||||
|
||||
int count_1 = 0;
|
||||
int count_3 = 0;
|
||||
bool found = false;
|
||||
|
||||
for (int i = 0; i < vector_size; ++i) {
|
||||
if (vec[i] == 1) count_1++;
|
||||
if (vec[i] == 3) count_3++;
|
||||
|
||||
if (i + 3 < vector_size) {
|
||||
if (vec[i] == 1 && vec[i + 1] == 9 && vec[i + 2] == 8 && vec[i + 3] == 9) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "Anzahl der 1en im Vektor: " << count_1 << std::endl;
|
||||
std::cout << "Anzahl der 3en im Vektor: " << count_3 << std::endl;
|
||||
|
||||
if (found) {
|
||||
std::cout << "Das Album \"1989\" von Taylor Swift ist ein sehr gutes Album." << std::endl;
|
||||
} else {
|
||||
std::cout << "\"1989\" kommt nicht vor." << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
void bubbleSort(std::vector<int>& zahlen) {
|
||||
unsigned n = zahlen.size();
|
||||
for (unsigned i = 0; i < n - 1; ++i) {
|
||||
for (unsigned j = 0; j < n - i - 1; ++j) {
|
||||
if (zahlen[j] > zahlen[j + 1]) {
|
||||
std::swap(zahlen[j], zahlen[j + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool binareSuche(std::vector<int>& zahlen, int start, int ende, int ziel) {
|
||||
while (start <= ende) {
|
||||
int mitte = start + (ende - start) / 2;
|
||||
if (zahlen[mitte] == ziel) {
|
||||
return true;
|
||||
} else if (zahlen[mitte] < ziel) {
|
||||
start = mitte + 1;
|
||||
} else {
|
||||
ende = mitte - 1;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
Funktion: sucheTriplets(std::vector<int>& X)
|
||||
Voraussetzungen:
|
||||
- Die Funktion nimmt als Argument einen Vektor von Ganzzahlen (std::vector<int>).
|
||||
- Der Vektor kann leer sein oder eine beliebige Anzahl von Ganzzahlen enthalten.
|
||||
- Die Zahlen im Vektor können positiv, negativ oder null sein.
|
||||
- Es wird angenommen, dass die Größe des Vektors in einem Bereich liegt, der für die verfügbare Speicherkapazität und Rechenleistung des Systems handhabbar ist.
|
||||
|
||||
Ergebnis:
|
||||
- Die Funktion gibt kein Ergebnis zurück (void Rückgabetyp).
|
||||
- Die Funktion druckt alle Tripel von Zahlen in der Eingabesequenz aus, für die die Summe der ersten beiden Zahlen gleich der dritten Zahl ist. Jedes Tripel wird in der Form "(a, b, c)" ausgegeben, wobei "a + b = c" gilt.
|
||||
- Wenn keine solchen Tripel existieren, gibt die Funktion nichts aus.
|
||||
|
||||
Effekte:
|
||||
- Die Funktion sortiert den Eingabevektor. Daher wird der Zustand des Eingabevektors geändert: die Elemente werden in aufsteigender Reihenfolge angeordnet.
|
||||
- Die Funktion hat keinen weiteren Seiteneffekt auf den Zustand des Programms. Sie ändert keine globalen Variablen und hat keine Auswirkungen auf den Zustand des Systems außerhalb des Programms.
|
||||
- Die Funktion kann eine beträchtliche Menge an Ausgabe produzieren, wenn viele gültige Tripel existieren. Dies könnte die Leistung des Systems beeinträchtigen, wenn die Ausgabe in eine Datei umgeleitet wird oder wenn das System über begrenzte Ressourcen für die Ausgabeverwaltung verfügt.
|
||||
- Die Funktion verwendet zusätzlichen Speicher für das unordered_set, das zur Speicherung der Elemente des Eingabevektors verwendet wird. Die Menge des benötigten Speichers ist proportional zur Größe des Eingabevektors.
|
||||
*/
|
||||
|
||||
void findeTripel(std::vector<int>& zahlen) {
|
||||
bubbleSort(zahlen);
|
||||
|
||||
for (unsigned i = 0; i < zahlen.size(); ++i) {
|
||||
for (unsigned j = i + 1; j < zahlen.size(); ++j) {
|
||||
int summe = zahlen[i] + zahlen[j];
|
||||
if (binareSuche(zahlen, 0, zahlen.size() - 1, summe)) {
|
||||
std::cout << "(" << zahlen[i] << ", " << zahlen[j] << ", " << summe << ")\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::vector<int> zahlen = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
findeTripel(zahlen);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
|
||||
/*
|
||||
(a) hat eine Zeitkomplexität von O(n), wobei n die Anzahl der Elemente in vec ist.
|
||||
Das liegt daran, dass jede Operation in der for-Schleife in konstanter Zeit ausgeführt wird
|
||||
und die Schleife genau n-Mal durchlaufen wird.
|
||||
*/
|
||||
|
||||
int vector_summe(vector<int>& vec){
|
||||
int sum = 0;
|
||||
for (unsigned i =0; i < vec.size(); i++){
|
||||
sum +=vec[i];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
/*
|
||||
(b) hat eine Zeitkomplexität von O(n^2), da es zwei verschachtelte Schleifen gibt,
|
||||
die jeweils bis zur Größe des Vektors laufen.
|
||||
Dies bedeutet, dass für jedes Element in vec alle Elemente innerhalb des Elementes einmal betrachtet werden,
|
||||
was zu n*n Operationen führt.
|
||||
*/
|
||||
|
||||
vector<pair<int, int>> pairs(vector<int>& vec){
|
||||
vector<pair<int, int>> returnpairs;
|
||||
pair<int, int> p;
|
||||
for(unsigned i = 0; i<vec.size(); i++){
|
||||
for(unsigned j=0; j<vec.size(); j++){
|
||||
p = {vec[i], vec[j]};
|
||||
returnpairs.push_back(p);
|
||||
}
|
||||
}
|
||||
return returnpairs;
|
||||
}
|
||||
|
||||
/*
|
||||
(c) Die Eingabegröße n ist die Größe von vec1 und m ist die Größe von vec2.
|
||||
Zuerst werden die separate Listen, vec1 und vec2, separat sortiert.
|
||||
Die Zeitkomplexität für das Sortieren von vec1 ist O(n log n) und O(m log m) für das Sortieren von vec2,
|
||||
da das die Zeitkomplexität von mergesort ist.
|
||||
Die anschließenden verschachtelten Schleifen, die über die beiden Vektoren iterieren, haben eine Zeitkomplexität von O(n*m),
|
||||
da jede Kombination aus Elementen von vec1 und vec2 einmal betrachtet wird.
|
||||
Daher ist die gesamte Zeitkomplexität O(n log n + m log m + n*m).
|
||||
Die Anzahl der Operationen entspricht im Wesentlichen der Zeitkomplexität.
|
||||
*/
|
||||
|
||||
vector<pair<int, int>> sorted_pairs(vector<int> vec1, vector<int> vec2){
|
||||
vector<pair<int, int>> returnpairs;
|
||||
pair<int, int> p;
|
||||
mergeSort(vec1);
|
||||
mergeSort(vec2);
|
||||
for(unsigned i = 0; i < vec1.size(); i++){
|
||||
for(unsigned j = 0; j < vec2.size(); j++){
|
||||
p = {vec1[i], vec2[j]};
|
||||
returnpairs.push_back(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
enum Abteilung {
|
||||
IT,
|
||||
FINANZ,
|
||||
MARKETING,
|
||||
PERSONAL,
|
||||
PRODUKTION
|
||||
};
|
||||
|
||||
struct angestellter {
|
||||
std::string name;
|
||||
int personalnummer;
|
||||
Abteilung abteilung;
|
||||
double gehalt;
|
||||
};
|
||||
|
||||
angestellter angestellter_eingeben();
|
||||
std::vector<angestellter> abteilung_check(std::vector<angestellter> vec, Abteilung abt);
|
||||
|
||||
int main() {
|
||||
|
||||
angestellter beispielAngestellter = angestellter_eingeben();
|
||||
|
||||
std::cout << std::endl << "Angestellter:" << std::endl;
|
||||
std::cout << "Name: " << beispielAngestellter.name << std::endl;
|
||||
std::cout << "Personalnummer: " << beispielAngestellter.personalnummer << std::endl;
|
||||
std::cout << "Abteilung: " << beispielAngestellter.abteilung << std::endl;
|
||||
std::cout << "Gehalt: " << beispielAngestellter.gehalt << std::endl;
|
||||
|
||||
angestellter kollege1 = {"Hans Wurst", 678, PRODUKTION, 3550.5};
|
||||
angestellter kollege2 = {"Scrooge McDough", 022, FINANZ, 4702};
|
||||
angestellter kollege3 = {"Ninja Scripter", 337, IT, 2500};
|
||||
angestellter kollege4 = {"Snake Oil", 888, MARKETING, 1800};
|
||||
angestellter kollege5 = {"Overlord", 007, PERSONAL, 5600};
|
||||
|
||||
std::vector<angestellter> belegschaft = {kollege1, kollege2, kollege3, kollege4, kollege5};
|
||||
std::vector<angestellter> filtered = abteilung_check(belegschaft, beispielAngestellter.abteilung);
|
||||
|
||||
// Display filtered employees or a message if no matching employees are found.
|
||||
if (!filtered.empty()) {
|
||||
for (const auto& ang : filtered) {
|
||||
std::cout << "Filtered employee: " << ang.name << std::endl;
|
||||
}
|
||||
} else {
|
||||
std::cout << "No matching employees found." << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<angestellter> abteilung_check(std::vector<angestellter> vec, Abteilung abt) {
|
||||
std::vector<angestellter> division;
|
||||
for (const auto &ang : vec) {
|
||||
if (ang.abteilung == abt) {
|
||||
division.push_back(ang);
|
||||
}
|
||||
}
|
||||
return division;
|
||||
}
|
||||
|
||||
angestellter angestellter_eingeben() {
|
||||
angestellter neuerAngestellter;
|
||||
int abteilungWahl;
|
||||
std::cout << "Name: ";
|
||||
std::getline(std::cin, neuerAngestellter.name);
|
||||
std::cout << "Personalnummer: ";
|
||||
std::cin >> neuerAngestellter.personalnummer;
|
||||
|
||||
std::cout << "Abteilung (0: IT, 1: FINANZ, 2: MARKETING, 3: PERSONAL, 4: PRODUKTION): ";
|
||||
std::cin >> abteilungWahl;
|
||||
neuerAngestellter.abteilung = static_cast<Abteilung>(abteilungWahl);
|
||||
|
||||
std::cout << "Gehalt: ";
|
||||
std::cin >> neuerAngestellter.gehalt;
|
||||
std::cin.ignore();
|
||||
|
||||
return neuerAngestellter;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/* Informatik B - Sommersemester 2022
|
||||
Vorlesung am 21.04.2022
|
||||
Katharina Klost
|
||||
|
||||
Beispiele zu arithmetischen Operationen
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
int main(){
|
||||
/* Unterschiede zwische Post- und Preinkrement:
|
||||
|
||||
Beim Postinkrement wird der Wert *erst* ausgewertet und dann erhöht,
|
||||
daher wird in der zweiten Zeile noch einmal 2 und erst in der dritten
|
||||
Zeile 3 ausgegeben.
|
||||
Bei Preinkrement wird erst erhöht und dann ausgegeben, daher wird in der
|
||||
vierten und fünften Zeile 4 ausgegeben.
|
||||
*/
|
||||
int n =2;
|
||||
std::cout << "Vor Postinkrement " << n << std::endl;
|
||||
std::cout << "Postinkrement " << n++ << std::endl;
|
||||
std::cout << "Nach Postinkrement " << n << std::endl;
|
||||
std::cout << "Preinkrement " << ++n << std::endl;
|
||||
std::cout << "Nach Preinkrement " << n << std::endl;
|
||||
|
||||
// += als vereinfachte Schreibweise für n = n + 3;
|
||||
n+=3;
|
||||
std::cout << n << std::endl;
|
||||
|
||||
// k und k1 haben auf Grund der Bindunststärken den gleichen Wert
|
||||
int k1 = 7*4 + ++n/4;
|
||||
int k = (7*4)+ ((++n) / 4);
|
||||
std::cout << "k1: " << k1 << ", k: " <<k << std::endl;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
|
||||
int main(){
|
||||
int n1 = 10;
|
||||
int n2 = 20;
|
||||
int n3 = n1/n2;
|
||||
float f1 = 10;
|
||||
float f2 = f1 + 10;
|
||||
float f3 = f1/f2;
|
||||
|
||||
cout << "n3: " << n3 << endl;
|
||||
cout << "f3: " << f3 << endl;
|
||||
|
||||
f3 += 3;
|
||||
cout << "f3: " << f3++ << endl;
|
||||
cout << "f3: mit postincr " << f3++ << endl;
|
||||
cout << "f3: mit preincr " << ++f3 << endl;
|
||||
|
||||
bool comp1 = 2*5+5*2 == n2;
|
||||
n2 = n2*2;
|
||||
bool comp2 = 2*5+5*2 == n2;
|
||||
bool comp3 = n3 < f3;
|
||||
|
||||
bool comp4 = comp1 && comp3 || comp2;
|
||||
cout << "comp1, comp2, comp3, comp4: " << comp1 << ", " << comp2 << ", " << comp3 << ", " << comp4 << endl;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// g++ -std=c++14 -Wall -Wextra -Werror -pedantic ./w4/binarysearch.cpp -o ./bin/binarysearch
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
int binarySearch(int query, std::vector<int> &elems)
|
||||
{
|
||||
unsigned low = 0;
|
||||
unsigned high = elems.size() - 1;
|
||||
unsigned index = (low + high) / 2;
|
||||
while (low < high)
|
||||
{
|
||||
if (query == elems[index])
|
||||
{
|
||||
return elems[index];
|
||||
}
|
||||
if (query < elems[index])
|
||||
{
|
||||
high = index - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
low = index + 1;
|
||||
}
|
||||
index = (low + high) / 2;
|
||||
}
|
||||
return elems[index];
|
||||
}
|
||||
int main()
|
||||
{
|
||||
std::vector<int> searchtest = {1, 4, 6, 12, 19, 22, 34, 36, 100};
|
||||
std::cout << "Binärsuche: " << binarySearch(36, searchtest) << std::endl;
|
||||
std::cout << "Binärsuche: " << binarySearch(1000, searchtest) << std::endl;
|
||||
std::cout << "Binärsuche: " << binarySearch(0, searchtest) << std::endl;
|
||||
std::cout << "Binärsuche: " << binarySearch(5, searchtest) << std::endl;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
// g++ -std=c++14 -Wall -Wextra -Werror -pedantic ./w4/bubblesort.cpp -o ./bin/bubblesort
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
void bubbleSort(std::vector<int>& arr, bool ascending) {
|
||||
int n = arr.size();
|
||||
|
||||
for (int i = 0; i < n - 1; ++i) {
|
||||
bool swapped = false;
|
||||
for (int j = 0; j < n - i - 1; ++j) {
|
||||
if ((arr[j] > arr[j + 1] && ascending) || (arr[j] < arr[j + 1] && !ascending)) {
|
||||
int temp = arr[j];
|
||||
arr[j] = arr[j + 1];
|
||||
arr[j + 1] = temp;
|
||||
swapped = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!swapped) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
int arr[] = {30, 10, 25, 100, 5, 16};
|
||||
int n = sizeof(arr) / sizeof(arr[0]);
|
||||
std::vector<int> numbers(arr, arr + n);
|
||||
bool ascending = true;
|
||||
|
||||
// Ascending sort
|
||||
bubbleSort(numbers, ascending);
|
||||
|
||||
std::cout << "Sorted list (ascending): ";
|
||||
for (unsigned i = 0; i < numbers.size(); ++i) {
|
||||
std::cout << numbers[i] << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
// Descending sort
|
||||
ascending = false;
|
||||
bubbleSort(numbers, ascending);
|
||||
|
||||
std::cout << "Sorted list (descending): ";
|
||||
for (unsigned i = 0; i < numbers.size(); ++i) {
|
||||
std::cout << numbers[i] << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// g++ -std=c++14 -Wall -Wextra -Werror -pedantic ./w7/call_by_reference_pointer.cpp -o ./bin/call_by_reference_pointer && ./bin/call_by_reference_pointer
|
||||
#include <iostream>
|
||||
|
||||
/*
|
||||
Voraussetzungen:
|
||||
Ein gültiger Zeiger auf ein Integer-Objekt muss als Argument an die Funktion übergeben werden.
|
||||
Der Zeiger darf nicht null und darf nicht auf Speicher zeigen, der nicht verändert werden darf (z.B. konstante Daten oder bereits freigegebener Speicher).
|
||||
|
||||
Ergebnis:
|
||||
Die Funktion hat keinen Rückgabewert.
|
||||
|
||||
Effekt:
|
||||
Die Funktion verändert den Wert der Integer-Variablen, auf die der übergebene Zeiger zeigt, zu 10.
|
||||
*/
|
||||
|
||||
void aendern(int *ptr)
|
||||
{
|
||||
*ptr = 10;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int x = 5;
|
||||
std::cout << "Davor: " << x << std::endl;
|
||||
aendern(&x);
|
||||
std::cout << "Danach: " << x << std::endl;
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/* Informatik B - Sommersemester 2023
|
||||
Vorlesung am 03.05.2023
|
||||
Katharina Klost
|
||||
|
||||
Weiteres Beispiel zur Rekursion
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
/*
|
||||
Voraussetzung: n ist größer als 0
|
||||
Ergebnis: Wenn Collatz mit n/2 terminiert ist true geliefert
|
||||
Effekt: keiner
|
||||
*/
|
||||
bool c1(unsigned);
|
||||
|
||||
|
||||
/*
|
||||
Voraussetzung: n ist größer als 0
|
||||
Ergebnis: Wenn Collatz mit 3*n+1 terminiert ist true geliefert
|
||||
Effekt: keiner
|
||||
*/
|
||||
bool c2(unsigned);
|
||||
|
||||
/*
|
||||
Voraussetzung: n ist größer als 0
|
||||
Ergebnis: true, wenn die Collatzfolge von n aus terminiert
|
||||
Effekt: gibt aktuellen Wert n aus
|
||||
*/
|
||||
bool collatz(unsigned);
|
||||
|
||||
bool c1(unsigned n){
|
||||
return collatz(n/2);
|
||||
}
|
||||
|
||||
bool collatz(unsigned n){
|
||||
std::cout << n << std::endl;
|
||||
if (n==1){
|
||||
return true;
|
||||
}
|
||||
// !(n%2) ist true, wenn n gerade ist. Dies kann wie folgt gesehen werden:
|
||||
// für gerade n ist n%2 == 0. Das Anwenden von ! interpretiert die 0 dann als
|
||||
// false, dieses wird negiert und damit wird der Ausdruck zu true ausgewertet.
|
||||
// Etwas länger aber evtl besser zu lesen wär (n%2 == 0).
|
||||
if (!(n%2)){
|
||||
return c1(n);
|
||||
}else{ // n ungerade
|
||||
return c2(n);
|
||||
}
|
||||
}
|
||||
|
||||
bool c2(unsigned n){
|
||||
return collatz(3*n+1);
|
||||
}
|
||||
|
||||
int main(){
|
||||
int n;
|
||||
std::cout << "Gebe eine Zahl ein: ";
|
||||
std::cin >> n;
|
||||
collatz(n);
|
||||
std::cout << "terminated" << std::endl;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/* Informatik B - Sommersemester 2023
|
||||
Vorlesung am 28.04.2023
|
||||
Katharina Klost
|
||||
|
||||
Beispiele zur Kombination von zusammengesetzen Datentypen
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
enum class wohnart{HAUS,WOHNUNG};
|
||||
|
||||
struct person{
|
||||
std::string name;
|
||||
wohnart wa;
|
||||
unsigned telefonnummer;
|
||||
};
|
||||
|
||||
int main(){
|
||||
|
||||
// eine person hat unter anderem einen enum als Feld und kann in einem
|
||||
// vector gespeichert werden
|
||||
std::vector<person> telefonbuch = {};
|
||||
|
||||
for(unsigned i=0; i< 30; i++){
|
||||
person p = {"Name"+std::to_string(i) , static_cast<wohnart>((3*i-1)%2), (i*300+23+i/2)};
|
||||
telefonbuch.push_back(p);
|
||||
}
|
||||
|
||||
person eintrag;
|
||||
for(unsigned i= 0 ; i< telefonbuch.size(); i++){
|
||||
eintrag = telefonbuch[i];
|
||||
if(eintrag.wa == wohnart::HAUS){
|
||||
std::cout << eintrag.name << " wohnt in einem Haus" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::string query;
|
||||
std::cout << "Welcher Name soll gesucht werden? " ;
|
||||
std::cin >> query;
|
||||
bool found = false;
|
||||
for (unsigned i= 0; i< telefonbuch.size()&&!found; i++){
|
||||
eintrag = telefonbuch[i];
|
||||
if (eintrag.name == query){
|
||||
std::cout << eintrag.name << " hat Telefonnummer: "<< eintrag.telefonnummer << std::endl;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found){
|
||||
std::cout << query << " ist nicht im Telefonbuch enthalten" << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/* Informatik B - Sommersemester 2022
|
||||
Vorlesung am 21.04.2022
|
||||
Katharina Klost
|
||||
|
||||
Beispiele zu Datentypen
|
||||
*/
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <climits>
|
||||
|
||||
int main(){
|
||||
//Auf Grund der Wertsemantik wird nur der Inhalt von num 3 verändert
|
||||
int num2 = 20;
|
||||
int num3 = num2;
|
||||
std::cout << "num 2: " << num2 << std::endl;
|
||||
std::cout << "num 3: " << num3 << std::endl;
|
||||
num3 = num3 +1;
|
||||
std::cout << "num 2: " << num2 << std::endl;
|
||||
std::cout << "num 3: " << num3 << std::endl;
|
||||
|
||||
/*Auch wenn in einem Bool allgeine Werte gespeichert werden können
|
||||
wird nur 0 für false und 1 für alle Werte != 0 ausgegeben*/
|
||||
bool b1 = 12;
|
||||
std::cout << "b1: " << b1 << std::endl;
|
||||
std::cout << "Größe von b1: " << sizeof(b1) << std::endl;
|
||||
|
||||
//Da chars intern als Zahlen gespeichert werden, kann mit diesen auch
|
||||
//gerechnet werden
|
||||
char c1 = 'A';
|
||||
|
||||
std::cout << "c1: " << c1 << std::endl;
|
||||
c1=c1+1;
|
||||
std::cout << "c1: " << c1 << std::endl;
|
||||
|
||||
//Bei Integern kann es zu einem Überlauf kommen
|
||||
int n = INT_MAX;
|
||||
std::cout << n << std::endl;
|
||||
n= n+1;
|
||||
std::cout << n << std::endl;
|
||||
|
||||
// Bei Floats kann es wegen Rundungsfehlern zu unerwartetem Verhalten kommen
|
||||
float x = 0;
|
||||
for (int i = 0; i < 10; i++){
|
||||
x = x + 0.1;
|
||||
std::cout << "x"<<i <<" :"<< x << std::endl;
|
||||
}
|
||||
|
||||
std::cout <<"(x==1.0) " << (x==1.0) << std::endl;
|
||||
|
||||
//Größen von verschiedenen Datentypen
|
||||
short s1 = 123;
|
||||
long l1 = 123;
|
||||
long long ll1 = 123;
|
||||
float f1 = 123.0;
|
||||
double d1 = 123.0;
|
||||
long double ld1 = 123.0;
|
||||
|
||||
|
||||
// Größen der Datentypen (auf diesem System)
|
||||
std::cout << "Größen verschiedener Datentypen in Byte" << std::endl;
|
||||
std::cout << "bool: " << sizeof(b1) << std::endl;
|
||||
std::cout << "char: " << sizeof(c1) << std::endl;
|
||||
std::cout << "short: " << sizeof(s1) << std::endl;
|
||||
std::cout << "int: " << sizeof(n) << std::endl;
|
||||
std::cout << "long: " << sizeof(l1) << std::endl;
|
||||
std::cout << "long long: " << sizeof(ll1) << std::endl;
|
||||
std::cout << "float: " << sizeof(f1) << std::endl;
|
||||
std::cout << "double: " << sizeof(d1) << std::endl;
|
||||
std::cout << "long double: " << sizeof(ld1) << std::endl;
|
||||
|
||||
std::cout << "Größe eines Bytes in Bit: " << CHAR_BIT << std::endl;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/* Informatik B - Sommersemester 2023
|
||||
Vorlesung am 26.04.2023
|
||||
Katharina Klost
|
||||
|
||||
Beispiele zur Deklaration und Initialisierung von Variablen
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
int main(){
|
||||
int num1;
|
||||
//num1 ist nur deklariert und nicht initialisiert und daher ist
|
||||
//der Inhalt hier nicht definiert (irgendein Wert)
|
||||
std::cout << num1 << std::endl;
|
||||
|
||||
num1 = 10;
|
||||
|
||||
std::cout << num1 << std::endl;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/* Informatik B - Sommersemester 2023
|
||||
Vorlesung am 28.04.2023
|
||||
Katharina Klost
|
||||
|
||||
Beispiele zu enums
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
//Ein enum für Wochentage
|
||||
enum class Wochentag{
|
||||
Montag,
|
||||
Dienstag,
|
||||
Mittwoch,
|
||||
Donnerstag,
|
||||
Freitag,
|
||||
Samstag,
|
||||
Sonntag
|
||||
};
|
||||
|
||||
|
||||
//Ein enum für Farben
|
||||
enum class Farbe {rot, gruen, blau, orange};
|
||||
|
||||
// Ein enum für die Zustände von Ampeln
|
||||
enum class Ampel {gruen, gelb, rot, gelb_rot};
|
||||
|
||||
int main(){
|
||||
// der Name des enums muss immer angegeben werden, da es Felder mit
|
||||
// dem gleichen Namen in verschiedenen enums geben kann
|
||||
Ampel ampel1 = Ampel::gruen;
|
||||
//enums und switch-case sind eine beliebte Kombination
|
||||
switch(ampel1){
|
||||
case Ampel::gruen:
|
||||
std::cout << "Kann fahren" << std::endl;
|
||||
break;
|
||||
case Ampel::gelb:
|
||||
std::cout << "Achtung" << std::endl;
|
||||
break;
|
||||
case Ampel::rot:
|
||||
std::cout << "Stop" << std::endl;
|
||||
break;
|
||||
case Ampel::gelb_rot:
|
||||
std::cout << "Achtung" << std::endl;
|
||||
break;
|
||||
default:
|
||||
std::cout <<"Irgendwas anderes" << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
int number;
|
||||
std::cout << "Gebe einen Tag ein, (Montag=1,..., Sonntag =7)";
|
||||
std::cin >> number;
|
||||
// da enums intern mit Zahlen dargestellt werden, können Zahlen
|
||||
// explizit in eine enum umgewandelt werden
|
||||
Wochentag tag = static_cast<Wochentag>(number-1);
|
||||
|
||||
// werden enums verglichen gilt die Reihenfolge in der Definition
|
||||
if (tag >= Wochentag::Samstag){
|
||||
std::cout << "Es ist Wochenende :)" << std::endl;
|
||||
}
|
||||
else{
|
||||
std::cout << "Es ist ein Arbeitstag :(" << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/* Informatik B - Sommersemester 2023
|
||||
Vorlesung am 05.05.2023
|
||||
Katharina Klost
|
||||
|
||||
Verschiedene Umsetzungen des euklidischen Algorithmus
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
/*
|
||||
Voraussetzung: keine
|
||||
Effekt: Es werden Informationen zum Ablauf ausgegeben
|
||||
Ergebnis: Der größte gemeinsame Teiler von a und b ist geliefert
|
||||
*/
|
||||
// Rekursive Umsetzung
|
||||
unsigned euclid_rec(unsigned a, unsigned b);
|
||||
//optimierte rekursive Umsetzung
|
||||
unsigned euclid_rec_opt(unsigned a, unsigned b);
|
||||
//iterative Umsetzung
|
||||
unsigned euclid_it(unsigned a, unsigned b);
|
||||
|
||||
|
||||
unsigned euclid_rec(unsigned a, unsigned b){
|
||||
std::cout << "ggT(" << a << ", " << b << ")" << std::endl;
|
||||
if (b>a){
|
||||
return euclid_rec(b,a);
|
||||
}
|
||||
if(b==0){
|
||||
return a;
|
||||
}
|
||||
return euclid_rec(a-b, b);
|
||||
}
|
||||
|
||||
// statt immer wieder a-b zu rechnen, bis das Ergebnis kleiner als b ist,
|
||||
// kann direkt modulu verwendet werden
|
||||
unsigned euclid_rec_opt(unsigned a, unsigned b){
|
||||
std::cout << "ggTopt(" << a<< ", " << b << ")" << std::endl;
|
||||
if(b==0){
|
||||
return a;
|
||||
}
|
||||
return euclid_rec_opt(b, a%b);
|
||||
}
|
||||
|
||||
//iterative Umsetzung des optimierten euklidischen Algorithmus
|
||||
unsigned euclid_it(unsigned a, unsigned b){
|
||||
unsigned newb;
|
||||
while(b!=0){
|
||||
newb = a%b;
|
||||
a=b;
|
||||
b = newb;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
int main(){
|
||||
int a= 12;
|
||||
int b= 136;
|
||||
std::cout << "===Rekursiv===" << std::endl;
|
||||
int ggT= euclid_rec(a , b);
|
||||
std::cout << "Der ggT von " << a << " und " << b << " ist " << ggT <<std::endl;
|
||||
std::cout << "===Rekursiv Optimiert ===" << std::endl;
|
||||
ggT= euclid_rec_opt(a , b);
|
||||
std::cout << "Der ggT von " << a << " und " << b << " ist " << ggT <<std::endl;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#include <iostream>
|
||||
|
||||
// Fibonacci numbers
|
||||
|
||||
int main() {
|
||||
|
||||
int x;
|
||||
std::cout << "x-th Fibonacci number?: ";
|
||||
std::cin >> x;
|
||||
|
||||
int prev = 0;
|
||||
int curr = 1;
|
||||
int tmp;
|
||||
|
||||
for (int i = 2; i <= x; ++i) {
|
||||
tmp = curr;
|
||||
curr = prev + curr;
|
||||
prev = tmp;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/* Informatik B - Sommersemester 2023
|
||||
Vorlesung am 26.04.2023
|
||||
Katharina Klost
|
||||
|
||||
Beispiele zu Gültigkeitsbereichen
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
int main (){
|
||||
|
||||
|
||||
int variable1;
|
||||
std::cin >> variable1;
|
||||
|
||||
float variable3;
|
||||
|
||||
if (variable1 == 10){
|
||||
float varible2 = 9.1;
|
||||
std::cout << varible2 << std::endl;
|
||||
}
|
||||
else{
|
||||
// neue Deklaration von variable3, überschattet die andere variable3
|
||||
float variable3 = 10.1;
|
||||
std::cout << variable3 << std::endl;
|
||||
}
|
||||
/*
|
||||
variable2 ist nur in der ersten if-Bedingung definiert und kann daher
|
||||
hier nicht verwendet werden.
|
||||
*/
|
||||
//std::cout << variable2 << std::endl;
|
||||
|
||||
//Da diese variable3 nur deklariert aber nicht initialisiert wurde,
|
||||
// ist der Inhalt hier beliebig
|
||||
std::cout << variable3 << std::endl;
|
||||
|
||||
variable3 = 1.1;
|
||||
|
||||
|
||||
while(variable1<10){
|
||||
//wird immer wieder neu deklariert
|
||||
int variable3 = variable1;
|
||||
std::cout << "variable3 in schleife: " << variable3 << std::endl;
|
||||
variable1++;
|
||||
}
|
||||
std::cout << "variable1 nach erster Schleife: " << variable1 << std::endl;
|
||||
std::cout << "variable3 nach erster Schleife: " << variable3 << std::endl;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
// g++ ./w6/heap.cpp -o ./bin/heap && ./bin/heap
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
class MaxHeap {
|
||||
private:
|
||||
std::vector<int> heap;
|
||||
|
||||
// Hilfsfunktionen zum Vertauschen von Elementen und zur Berechnung von Eltern- und Kindknotenindizes
|
||||
void swap(int& a, int& b) {
|
||||
int temp = a;
|
||||
a = b;
|
||||
b = temp;
|
||||
}
|
||||
|
||||
int getParentIndex(int index) {
|
||||
return (index - 1) / 2;
|
||||
}
|
||||
|
||||
int getLeftChildIndex(int index) {
|
||||
return (2 * index) + 1;
|
||||
}
|
||||
|
||||
int getRightChildIndex(int index) {
|
||||
return (2 * index) + 2;
|
||||
}
|
||||
|
||||
// Hilfsfunktion zum Wiederherstellen der Heap-Eigenschaft nach oben
|
||||
void heapifyUp(int index) {
|
||||
if (index == 0)
|
||||
return;
|
||||
|
||||
int parentIndex = getParentIndex(index);
|
||||
if (heap[parentIndex] < heap[index]) {
|
||||
swap(heap[parentIndex], heap[index]);
|
||||
heapifyUp(parentIndex);
|
||||
}
|
||||
}
|
||||
|
||||
// Hilfsfunktion zum Wiederherstellen der Heap-Eigenschaft nach unten
|
||||
void heapifyDown(int index) {
|
||||
int largest = index;
|
||||
int leftChildIndex = getLeftChildIndex(index);
|
||||
int rightChildIndex = getRightChildIndex(index);
|
||||
|
||||
if (leftChildIndex < heap.size() && heap[leftChildIndex] > heap[largest])
|
||||
largest = leftChildIndex;
|
||||
|
||||
if (rightChildIndex < heap.size() && heap[rightChildIndex] > heap[largest])
|
||||
largest = rightChildIndex;
|
||||
|
||||
if (largest != index) {
|
||||
swap(heap[index], heap[largest]);
|
||||
heapifyDown(largest);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
// Einfügen eines Elements in den Heap
|
||||
void insert(int value) {
|
||||
heap.push_back(value);
|
||||
heapifyUp(heap.size() - 1);
|
||||
}
|
||||
|
||||
// Entfernen des Maximums aus dem Heap
|
||||
int removeMax() {
|
||||
if (heap.empty())
|
||||
throw std::out_of_range("Heap is empty!");
|
||||
|
||||
int max = heap[0];
|
||||
heap[0] = heap.back();
|
||||
heap.pop_back();
|
||||
heapifyDown(0);
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
// Zugriff auf das Maximum im Heap
|
||||
int getMax() {
|
||||
return heap[0];
|
||||
}
|
||||
|
||||
// Prüfen, ob der Heap leer ist
|
||||
bool isEmpty() {
|
||||
return heap.empty();
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
MaxHeap heap;
|
||||
|
||||
// Beispielverwendung des Heaps
|
||||
heap.insert(10);
|
||||
heap.insert(7);
|
||||
heap.insert(15);
|
||||
heap.insert(30);
|
||||
heap.insert(20);
|
||||
|
||||
std::cout << "Max: " << heap.getMax() << std::endl;
|
||||
|
||||
heap.removeMax();
|
||||
|
||||
std::cout << "Max after removal: " << heap.getMax() << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/* Informatik B - Sommersemester 2022
|
||||
Vorlesung am 21.04.2022
|
||||
Katharina Klost
|
||||
|
||||
Beispiele zur Ein-und Ausgabe
|
||||
*/
|
||||
#include <iostream>
|
||||
|
||||
int main(){
|
||||
/* Der Text "Hello World!" wird auf der Konsole ausgegeben, gefolgt von einem
|
||||
Zeilenumbruch*/
|
||||
std::cout << "Hello World!" << std::endl;
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/* Informatik B - Sommersemester 2023
|
||||
Vorlesung am 12.05.2023
|
||||
Katharina Klost
|
||||
|
||||
Hilfsfunktionen zum Sortieren, nur zusammen mit der sorting.cpp zu compilieren
|
||||
*/
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include "hilfsfunktionen.hpp"
|
||||
|
||||
|
||||
namespace hf{
|
||||
|
||||
void gebe_aus(std::vector<int>& vec, unsigned start, unsigned end){
|
||||
if(end>vec.size()){
|
||||
std::cout << vec.size() << " " << end << std::endl;
|
||||
return;
|
||||
}
|
||||
std::cout << vec[start];
|
||||
for(unsigned k=start+1; k<end; k++){
|
||||
std::cout << ", " << vec[k];
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
void swap(std::vector<int>& elems, unsigned i, unsigned j){
|
||||
if (i>=elems.size() || j >= elems.size()){
|
||||
return;
|
||||
}
|
||||
int tmp = elems[i];
|
||||
elems[i] = elems[j];
|
||||
elems[j] = tmp;
|
||||
}
|
||||
|
||||
unsigned minimumIndex(std::vector<int>& elems, unsigned start, unsigned end){
|
||||
unsigned min = start;
|
||||
for(unsigned i = start; i<end; i++){
|
||||
if(elems[i] < elems[min]){
|
||||
min = i;
|
||||
}
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
std::vector<int> copy(std::vector<int>& elems, unsigned start, unsigned end){
|
||||
std::vector<int> returnVec;
|
||||
for(unsigned i= start; i<end; i++){
|
||||
returnVec.push_back(elems[i]);
|
||||
}
|
||||
return returnVec;
|
||||
}
|
||||
|
||||
bool generator_started = false;
|
||||
int zufall(int left, int right) {
|
||||
// Vor der ersten Zufallszahl muss der Zufallsgenerator gestartet werden.
|
||||
if (!generator_started) {
|
||||
srandom(time(NULL));
|
||||
generator_started = true;
|
||||
}
|
||||
return left + random() % (right-left);
|
||||
}
|
||||
|
||||
std::vector<int> sortiertes_array(unsigned size, bool aufsteigend) {
|
||||
std::vector<int> array(size);
|
||||
for (unsigned i = 0; i < size; i++)
|
||||
array[i] = aufsteigend * i + (!aufsteigend) * (size - i - 1);
|
||||
return array;
|
||||
}
|
||||
|
||||
std::vector<int> zufalls_array(unsigned size) {
|
||||
std::vector<int> array(size);
|
||||
for (unsigned i = 0; i < size; i++)
|
||||
array[i] = zufall(0, size);
|
||||
return array;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/* Informatik B - Sommersemester 2023
|
||||
Vorlesung am 12.05.2023
|
||||
Katharina Klost
|
||||
|
||||
Headerdatei zu den Hilfsfunktionen zum Sortieren
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
// #include "telefonbuch.hpp"
|
||||
|
||||
namespace hf{
|
||||
/*
|
||||
Voraussetzung: 0 <= start <= end < vec.elems()
|
||||
Ergebnis: Keins
|
||||
Effekt: Gibt die Elemente des Vektors im Intervall [start,end) aus
|
||||
*/
|
||||
void gebe_aus(std::vector<int>& elems, unsigned start, unsigned end);
|
||||
|
||||
/*
|
||||
Voraussetzung: 0<=start<=end < vec.elems()
|
||||
Ergebnis: Ein vector, mit alle Elemente im Intervall [start, end)
|
||||
Effekt: Keiner
|
||||
*/
|
||||
std::vector<int> copy(std::vector<int>& elems, unsigned start, unsigned end);
|
||||
|
||||
/*
|
||||
Voraussetzung: 0 <= i,j <= elems.size()
|
||||
Ergebnis: Keins
|
||||
Effekt: Tauscht die Einträge and Position i und j
|
||||
*/
|
||||
void swap(std::vector<int>& elems, unsigned i, unsigned j);
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Voraussetzung: Es gilt 0 <= start <= end < elems.size()
|
||||
Effekt: Keiner
|
||||
Ergebni: Index des kleinesten Elements zwischen start und end
|
||||
*/
|
||||
unsigned minimumIndex(std::vector<int>& elems, unsigned start, unsigned end);
|
||||
|
||||
|
||||
/*
|
||||
Voraussetzung: left < right
|
||||
Ergebnis: Eine Zufallszahl zwischen left(inklusive) und right (exklusive)
|
||||
Effekt: Keiner
|
||||
*/
|
||||
int zufall(int left, int right);
|
||||
|
||||
/*
|
||||
Voraussetzung: Keine
|
||||
Effekt: Keiner
|
||||
Ergebnis: Ein sortierter vector ist geliefert. Wenn aufsteigend=true ist der vector aufsteigend sortiert, sonst absteigends
|
||||
*/
|
||||
std::vector<int> sortiertes_array(unsigned size, bool aufsteigend);
|
||||
|
||||
/*
|
||||
Voraussetzung: Keine
|
||||
Effekt: Keiner
|
||||
Ergebnis: Ein vector mit zufälligen Werten ist geliefert. Hierbei wird jede Zahl gleichverteilt
|
||||
zufällig zwischen 0 und size gewählt. Doppelte Zahlen sind möglich.
|
||||
*/
|
||||
std::vector<int> zufalls_array(unsigned size);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
Arbeiten mit Dateien in C++:
|
||||
- Datei öffnen
|
||||
- Datei lesen
|
||||
- Datei schließen
|
||||
Quelle: https://cplusplus.com/reference/fstream/
|
||||
|
||||
histogram() ist eine Funktion, die ein Histogramm der Buchstaben in einem String erstellt.
|
||||
- Vorraussetzungen: str ist ein String
|
||||
- Ergebnis: hist ist ein Vektor, der die Häufigkeit der Buchstaben in str enthält
|
||||
- Seiteneffekte: keine
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
std::vector<int> histogram(std::string str);
|
||||
|
||||
int main() {
|
||||
|
||||
std::ifstream inputFile("moby.txt");
|
||||
|
||||
std::string content, line;
|
||||
|
||||
while (std::getline(inputFile, line)) {
|
||||
content += line;
|
||||
}
|
||||
|
||||
std::vector<int> hist = histogram(content);
|
||||
|
||||
for (unsigned i = 0; i < 26; i++) {
|
||||
if (hist[i] > 0) {
|
||||
std::cout << static_cast<char>('a' + i) << ": " << hist[i] << ", ";
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned i = 26; i < hist.size(); i++) { // Loop for uppercase letters
|
||||
if (hist[i] > 0) {
|
||||
std::cout << static_cast<char>('A' + i - 26) << ": " << hist[i] << ", ";
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
inputFile.close();
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
std::vector<int> histogram(std::string str) {
|
||||
|
||||
std::vector<int> hist(52, 0);
|
||||
|
||||
for (unsigned i = 0; i < str.length(); i++) {
|
||||
|
||||
if (str[i] >= 'a' && str[i] <= 'z') {
|
||||
hist[str[i] - 'a']++;
|
||||
}
|
||||
|
||||
else if (str[i] >= 'A' && str[i] <= 'Z') {
|
||||
hist[str[i] - 'A' + 26]++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return hist;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
g++ -std=c++14 -Wall -Wextra -Werror -pedantic ./w4/hilfsfunktionen.cpp ./w4/insertionsort.cpp -o ./bin/insertionsort
|
||||
|
||||
Insertion Sort funktioniert, indem es durch das Array läuft und jedes Element nach links verschiebt,
|
||||
bis es das erste Element findet, das kleiner ist. Dieser Prozess wird für jedes Element im Array wiederholt,
|
||||
bis das gesamte Array sortiert ist. Im Hauptprogramm (main) wird der Insertion Sort Algorithmus auf ein Testarray angewendet
|
||||
und das Array vor und nach der Sortierung ausgegeben.
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
#include "hilfsfunktionen.hpp"
|
||||
|
||||
void insertionSort(std::vector<int>& elems){
|
||||
// Der Schlüssel ist das Element, das wir gerade sortieren
|
||||
int key=elems[0];
|
||||
unsigned shiftindex;
|
||||
|
||||
// Beginne mit dem zweiten Element (Index 1)
|
||||
for(unsigned i = 1; i<elems.size();i++){
|
||||
// Aktualisiere den Schlüssel auf das aktuelle Element
|
||||
key=elems[i];
|
||||
|
||||
// Verschiebe jedes Element, das größer als der Schlüssel ist, um eine Position nach rechts
|
||||
for(shiftindex=i; shiftindex>0&&elems[shiftindex-1]>=key;shiftindex--){
|
||||
elems[shiftindex] = elems[shiftindex-1];
|
||||
}
|
||||
|
||||
// Füge den Schlüssel an der richtigen Position ein
|
||||
elems[shiftindex] = key;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(){
|
||||
std::vector<int> test = {1,4,2,67,3,76,13,8,10,22,6,9,5,11,32,0};
|
||||
hf::gebe_aus(test, 0, test.size());
|
||||
insertionSort(test);
|
||||
hf::gebe_aus(test, 0, test.size());
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/* Informatik B - Sommersemester 2022
|
||||
Vorlesung am 21.04.2022
|
||||
Katharina Klost
|
||||
|
||||
Beispiele zur Ein-und Ausgabe
|
||||
*/
|
||||
#include <iostream>
|
||||
|
||||
int main(){
|
||||
float a;
|
||||
//Ohne std::endl gibt es keinen Zeilenumbruch
|
||||
std::cout << "Gebe eine Zahl ein: ";
|
||||
// mit std::cin wird ein Wert von der Konsole gelesen und wenn möglich
|
||||
// in die passende Variable geschrieben
|
||||
std::cin >> a;
|
||||
// Das Ergebnis von Ausdrücken kann auf der Konsole ausgegeben werden
|
||||
std::cout << "a: " << a << std::endl;
|
||||
std::cout << "a mal zwei: " << a*2 << std::endl;
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
/*
|
||||
EScooter
|
||||
-------------------------
|
||||
- Marke: std::string
|
||||
- PS: int
|
||||
- Akku: int
|
||||
-------------------------
|
||||
+ EScooter(m: std::string, p: int, a: int)
|
||||
+ ~EScooter()
|
||||
+ getModell(): std::string
|
||||
+ getPS(): int
|
||||
+ getAkku(): int
|
||||
+ setPS(p: int): void
|
||||
+ operator<(other: EScooter): bool
|
||||
*/
|
||||
class EScooter
|
||||
{
|
||||
private:
|
||||
// Attribute
|
||||
std::string Marke;
|
||||
int PS;
|
||||
int Akku;
|
||||
|
||||
public:
|
||||
/*
|
||||
Voraussetzungen: Die Funktion kann mit einem String und zwei Integers aufgerufen werden.
|
||||
Ergebnis: Es wird kein Ergebnis zurückgegeben.
|
||||
Effekt: Ein neues EScooter-Objekt wird mit den angegebenen Marken-, PS- und Akkuwerten erstellt.
|
||||
*/
|
||||
EScooter(std::string m, int p, int a) : Marke(m), PS(p), Akku(a) {}
|
||||
|
||||
/*
|
||||
Voraussetzungen: Keine. Der Destruktor wird aufgerufen, wenn ein EScooter-Objekt gelöscht wird.
|
||||
Ergebnis: Es wird kein Ergebnis zurückgegeben.
|
||||
Effekt: Das EScooter-Objekt wird aus dem Speicher entfernt.
|
||||
*/
|
||||
~EScooter() {}
|
||||
|
||||
/*
|
||||
Voraussetzungen: Diese Methoden können aufgerufen werden, um die entsprechenden Attribute eines EScooter-Objekts zu erhalten.
|
||||
Ergebnis: Jede Methode gibt den entsprechenden Attributwert zurück.
|
||||
Effekt: Kein weiterer Effekt.
|
||||
*/
|
||||
std::string getModell()
|
||||
{
|
||||
return Marke;
|
||||
}
|
||||
|
||||
int getPS()
|
||||
{
|
||||
return PS;
|
||||
}
|
||||
|
||||
int getAkku()
|
||||
{
|
||||
return Akku;
|
||||
}
|
||||
|
||||
/*
|
||||
Voraussetzungen: Die Methode kann aufgerufen werden, um den PS-Wert eines EScooter-Objekts zu ändern.
|
||||
Ergebnis: Es wird kein Ergebnis zurückgegeben.
|
||||
Effekt: Der PS-Wert des EScooter-Objekts wird auf den übergebenen Wert gesetzt.
|
||||
*/
|
||||
void setPS(int p)
|
||||
{
|
||||
PS = p;
|
||||
}
|
||||
|
||||
/*
|
||||
Voraussetzungen: Die Methode kann aufgerufen werden, um zwei EScooter-Objekte auf der Basis ihrer PS-Werte zu vergleichen.
|
||||
Ergebnis: Die Methode gibt ein boolsches Ergebnis zurück, das angibt, ob das aktuelle EScooter-Objekt weniger PS hat als das andere.
|
||||
Effekt: Kein weiterer Effekt.
|
||||
*/
|
||||
bool operator<(const EScooter &other) const
|
||||
{
|
||||
return PS < other.PS;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Kochfeld
|
||||
-------------------------
|
||||
- Marke: std::string
|
||||
- AnzahlBrenner: int
|
||||
- istEingeschaltet: bool
|
||||
-------------------------
|
||||
+ Kochfeld(m: std::string, b: int)
|
||||
+ ~Kochfeld()
|
||||
+ getMarke(): std::strinsg
|
||||
+ getAnzahlBrenner(): int
|
||||
+ einschalten(): void
|
||||
+ ausschalten(): void
|
||||
+ istAn(): bool
|
||||
*/
|
||||
class Kochfeld
|
||||
{
|
||||
private:
|
||||
std::string Marke;
|
||||
int AnzahlBrenner;
|
||||
bool istEingeschaltet;
|
||||
|
||||
public:
|
||||
// Konstruktor
|
||||
Kochfeld(std::string m, int b) : Marke(m), AnzahlBrenner(b), istEingeschaltet(false) {}
|
||||
|
||||
// Destruktor
|
||||
~Kochfeld() {}
|
||||
|
||||
// Methoden
|
||||
std::string getMarke() const
|
||||
{
|
||||
return Marke;
|
||||
}
|
||||
|
||||
int getAnzahlBrenner() const
|
||||
{
|
||||
return AnzahlBrenner;
|
||||
}
|
||||
|
||||
void einschalten()
|
||||
{
|
||||
istEingeschaltet = true;
|
||||
}
|
||||
|
||||
void ausschalten()
|
||||
{
|
||||
istEingeschaltet = false;
|
||||
}
|
||||
|
||||
bool istAn() const
|
||||
{
|
||||
return istEingeschaltet;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
// Test EScooter
|
||||
EScooter meinScooter("voi", 250, 100);
|
||||
std::cout << "Marke: " << meinScooter.getModell() << std::endl;
|
||||
std::cout << "PS: " << meinScooter.getPS() << std::endl;
|
||||
std::cout << "Akku: " << meinScooter.getAkku() << std::endl;
|
||||
EScooter andererScooter("lime", 300, 120);
|
||||
std::cout << "Ist mein Scooter schwächer als der andere? " << (meinScooter < andererScooter ? "Ja" : "Nein") << std::endl;
|
||||
meinScooter.setPS(350);
|
||||
std::cout << "Nach dem Tuning: " << std::endl;
|
||||
std::cout << "PS: " << meinScooter.getPS() << std::endl;
|
||||
std::cout << "Ist mein Scooter jetzt schwächer als der andere? " << (meinScooter < andererScooter ? "Ja" : "Nein") << std::endl;
|
||||
|
||||
// Test Kochfeld
|
||||
Kochfeld meinKochfeld("Bosch", 4);
|
||||
std::cout << "Marke: " << meinKochfeld.getMarke() << std::endl;
|
||||
std::cout << "Anzahl der Brenner: " << meinKochfeld.getAnzahlBrenner() << std::endl;
|
||||
std::cout << "Ist das Kochfeld eingeschaltet? " << (meinKochfeld.istAn() ? "Ja" : "Nein") << std::endl;
|
||||
meinKochfeld.einschalten();
|
||||
std::cout << "Ist das Kochfeld eingeschaltet? " << (meinKochfeld.istAn() ? "Ja" : "Nein") << std::endl;
|
||||
meinKochfeld.ausschalten();
|
||||
std::cout << "Ist das Kochfeld eingeschaltet? " << (meinKochfeld.istAn() ? "Ja" : "Nein") << std::endl;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
class Konto
|
||||
{
|
||||
private:
|
||||
unsigned pin;
|
||||
int kontostand;
|
||||
|
||||
public:
|
||||
Konto(unsigned pin, int kontostand) : pin(pin), kontostand(kontostand) {}
|
||||
|
||||
void abheben(unsigned pin, unsigned betrag)
|
||||
{
|
||||
if (this->pin == pin)
|
||||
{
|
||||
kontostand = kontostand - betrag;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Falsche Pin.\n";
|
||||
}
|
||||
}
|
||||
|
||||
void einzahlen(unsigned pin, unsigned betrag)
|
||||
{
|
||||
if (this->pin == pin)
|
||||
{
|
||||
std::cout << "Alter Kontostand: " << kontostand << std::endl;
|
||||
kontostand = kontostand + betrag;
|
||||
std::cout << "Neuer Kontostand: " << kontostand << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Falsche Pin.\n";
|
||||
}
|
||||
}
|
||||
|
||||
void mehr_einzahlen(unsigned pin, std::vector<unsigned> betraege)
|
||||
{
|
||||
if (this->pin == pin)
|
||||
{
|
||||
for (unsigned i; i < betraege.size(); i++)
|
||||
kontostand = kontostand + betraege[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Falsche Pin.\n";
|
||||
}
|
||||
}
|
||||
|
||||
~Konto()
|
||||
{
|
||||
std::cout << "Konto wurde gelöscht.\n";
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
int betrag;
|
||||
std::cin >> betrag;
|
||||
Konto meinKonto(1234, 6000);
|
||||
meinKonto.einzahlen(1234, betrag);
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/* Informatik B - Sommersemester 2023
|
||||
Vorlesung am 26.04.2023
|
||||
Katharina Klost
|
||||
|
||||
Beispiele zu Kontrollstrukturen
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
|
||||
int main(){
|
||||
|
||||
/*
|
||||
Beispiel für eine komplexere if-then-else Abfrage.
|
||||
*/
|
||||
int num ;
|
||||
std::cout << "Gebe eine Zahl für den if test ein: " ;
|
||||
std::cin >> num;
|
||||
if (num == 2) {
|
||||
num = num*2;
|
||||
}
|
||||
else if (num > 1 && num <5) {
|
||||
num= num*3;
|
||||
}
|
||||
else if (num >=10){
|
||||
num = num*4;
|
||||
}
|
||||
else{
|
||||
num = num*5;
|
||||
}
|
||||
std::cout << num << std::endl;
|
||||
|
||||
/*
|
||||
Beispiel für eine switch-case umgebeung
|
||||
Die einzelnen case Abschnitte sind keine Blöcke, daher gibt es ohne
|
||||
break einen fallthrough und es können keine Variablen deklariert werden.
|
||||
|
||||
Bei modernen Compilern sollte es keine Unterschiede in der Performance
|
||||
von semantisch gleichen if-Bedingungen und switch-case Umgebungen geben
|
||||
*/
|
||||
int num1;
|
||||
std::cout << "Gebe eine Zahl für den switch-case test ein: ";
|
||||
std::cin >> num1;
|
||||
switch(num1){
|
||||
case 1:
|
||||
std::cout << "num ist 1" << std::endl; //kein break -> fallthrough
|
||||
case 2:
|
||||
std::cout << "num ist 1 oder 2" << std::endl;
|
||||
break;
|
||||
case 3:
|
||||
std::cout << "num ist 3" << std::endl;
|
||||
break;
|
||||
case 4:
|
||||
std::cout << "num ist 4" << std::endl;
|
||||
break;
|
||||
default:
|
||||
std::cout << "num ist nicht 1,2,3 oder 4" << std::endl;
|
||||
}
|
||||
|
||||
/*
|
||||
Beispiel für eine for-schleife, in <Anweisung3> und <Anweisung1> (vgl. Folien)
|
||||
Können auch mehrere Anweisungen mit , getrennt stehen.
|
||||
*/
|
||||
int num_for = 3;
|
||||
for (int counter=1; counter <=4; counter=counter+1, num_for ++) {
|
||||
num_for= num_for*num_for;
|
||||
std::cout << "num_for in iteration " << counter << ": "<< num_for << std::endl;
|
||||
}
|
||||
std::cout << "num_for nach Schleife: " << num_for << std::endl;
|
||||
|
||||
/*
|
||||
Beispiel für eine while-schleife
|
||||
*/
|
||||
int num_while = 2;
|
||||
int goal = 300;
|
||||
while (num_while < goal) {
|
||||
num_while = num_while * num_while;
|
||||
std::cout << "num_while after *: " << num_while << std::endl;
|
||||
}
|
||||
std::cout << num_while << std::endl;
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
#include <iostream>
|
||||
|
||||
class Maschine
|
||||
{
|
||||
private:
|
||||
bool status;
|
||||
bool kaputt;
|
||||
|
||||
public:
|
||||
Maschine(bool status, bool kaputt) : status(status), kaputt(kaputt) {}
|
||||
virtual ~Maschine() {}
|
||||
|
||||
void schalter()
|
||||
{
|
||||
status = !status;
|
||||
}
|
||||
virtual void schrotten()
|
||||
{
|
||||
kaputt = true;
|
||||
}
|
||||
bool ist_an()
|
||||
{
|
||||
return status && !kaputt;
|
||||
}
|
||||
};
|
||||
|
||||
class Waschmaschine : public Maschine
|
||||
{
|
||||
private:
|
||||
public:
|
||||
Waschmaschine(bool status, bool kaputt) : Maschine(status, kaputt) {}
|
||||
~Waschmaschine() {}
|
||||
void waschen()
|
||||
{
|
||||
if (ist_an())
|
||||
{
|
||||
std::cout << "Die Waschmaschine wäscht die Wäsche ...\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Die Waschmaschine ist aus oder kaputt ...\n";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class Spuellmaschine : public Maschine
|
||||
{
|
||||
private:
|
||||
public:
|
||||
Spuellmaschine(bool status, bool kaputt) : Maschine(status, kaputt) {}
|
||||
~Spuellmaschine() {}
|
||||
void spuelen()
|
||||
{
|
||||
if (ist_an())
|
||||
{
|
||||
std::cout << "Die Spüllmaschine spüllt ...\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Die Spüllmaschine ist aus oder kaputt ...\n";
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,91 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// Enum für die verschiedenen Menüpunkte
|
||||
enum MenuType {
|
||||
Vorspeise,
|
||||
Hauptgang,
|
||||
Dessert
|
||||
};
|
||||
|
||||
// Struct für die Details eines Menüpunkts
|
||||
struct MenuItem {
|
||||
MenuType type;
|
||||
std::string name;
|
||||
std::string description;
|
||||
double price;
|
||||
};
|
||||
|
||||
void showMenu(const std::vector<MenuItem>& menu) {
|
||||
for (size_t i = 0; i < menu.size(); ++i) {
|
||||
std::string type;
|
||||
switch (menu[i].type) {
|
||||
case Vorspeise:
|
||||
type = "Vorspeise";
|
||||
break;
|
||||
case Hauptgang:
|
||||
type = "Hauptgang";
|
||||
break;
|
||||
case Dessert:
|
||||
type = "Dessert";
|
||||
break;
|
||||
}
|
||||
std::cout << type << ": " << menu[i].name << " - " << menu[i].description << " (€" << menu[i].price << ")\n";
|
||||
}
|
||||
}
|
||||
|
||||
MenuItem searchMenuItem(const std::vector<MenuItem>& menu, const std::string& name) {
|
||||
for (size_t i = 0; i < menu.size(); ++i) {
|
||||
if (menu[i].name == name) {
|
||||
return menu[i];
|
||||
}
|
||||
}
|
||||
return MenuItem{static_cast<MenuType>(-1), "", "", -1.0};
|
||||
}
|
||||
|
||||
int main() {
|
||||
// Erstellen des Restaurantmenüs
|
||||
std::vector<MenuItem> menu = {
|
||||
{Vorspeise, "Bruschetta", "Geröstetes Brot mit Tomaten, Knoblauch und Basilikum", 5.0},
|
||||
{Hauptgang, "Spaghetti Bolognese", "Spaghetti mit würziger Hackfleisch-Tomatensauce", 10.0},
|
||||
{Dessert, "Tiramisu", "Italienisches Dessert aus Löffelbiskuit, Mascarpone und Kaffee", 6.0}
|
||||
};
|
||||
|
||||
std::cout << "Willkommen im Restaurant!\n";
|
||||
std::cout << "Möchten Sie das Menü anzeigen oder nach einem bestimmten Menüpunkt suchen?\n";
|
||||
std::cout << "1. Menü anzeigen\n";
|
||||
std::cout << "2. Nach Menüpunkt suchen\n";
|
||||
std::cout << "3. Beenden\n";
|
||||
|
||||
int option;
|
||||
std::cin >> option;
|
||||
|
||||
while (option != 3) {
|
||||
if (option == 1) {
|
||||
showMenu(menu);
|
||||
} else if (option == 2) {
|
||||
std::string name;
|
||||
std::cout << "Geben Sie den Namen des Menüpunkts ein, nach dem Sie suchen möchten: ";
|
||||
std::cin.ignore();
|
||||
std::getline(std::cin, name);
|
||||
MenuItem item = searchMenuItem(menu, name);
|
||||
if (item.price != -1.0) {
|
||||
std::cout << item.name << " - " << item.description << " (€" << item.price << ")\n";
|
||||
} else {
|
||||
std::cout << "Menüpunkt nicht gefunden.\n";
|
||||
}
|
||||
} else {
|
||||
std::cout << "Ungültige Option.\n";
|
||||
}
|
||||
|
||||
std::cout << "\nMöchten Sie das Menü anzeigen oder nach einem bestimmten Menüpunkt suchen?\n";
|
||||
std::cout << "1. Menü anzeigen\n";
|
||||
std::cout << "2. Nach Menüpunkt suchen\n";
|
||||
std::cout << "3. Beenden\n";
|
||||
std::cin >> option;
|
||||
}
|
||||
|
||||
std::cout << "Vielen Dank für Ihren Besuch! Auf Wiedersehen!\n";
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
g++ -std=c++14 -Wall -Wextra -Werror -pedantic ./w4/hilfsfunktionen.cpp ./w4/mergesort.cpp -o ./bin/mergesort
|
||||
|
||||
|
||||
Dieser Algorithmus verwendet den Divide-and-Conquer-Ansatz, um das Array zu sortieren. Zuerst wird das Array in zwei Hälften geteilt.
|
||||
Diese Hälften werden dann rekursiv sortiert (mit mergeSortHelp). Danach werden die beiden sortierten Hälften mit der merge Funktion
|
||||
zusammengeführt. Dieser Prozess wird fortgesetzt, bis das gesamte Array sortiert ist. Im Hauptprogramm (main) wird der Merge Sort
|
||||
Algorithmus auf ein Testarray angewendet und das Array vor und nach der Sortierung ausgegeben.
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
#include "hilfsfunktionen.hpp"
|
||||
|
||||
void merge(std::vector<int>& elems, unsigned begin, unsigned mid, unsigned end){
|
||||
// Kopiere die erste und zweite Hälfte des zu sortierenden Bereichs in neue Vektoren
|
||||
std::vector<int> firstHalf = hf::copy(elems, begin, mid);
|
||||
std::vector<int> secondHalf = hf::copy(elems, mid, end);
|
||||
|
||||
// Initialisiere Zähler für die beiden Hälften
|
||||
unsigned i = 0;
|
||||
unsigned j = 0;
|
||||
|
||||
// Iteriere durch den zu sortierenden Bereich
|
||||
while(begin + i + j < end){
|
||||
// Wenn alle Elemente aus der zweiten Hälfte kopiert wurden oder das aktuelle Element der ersten Hälfte kleiner ist als das der zweiten Hälfte
|
||||
if ( j >= secondHalf.size() || ((i<firstHalf.size()) && (firstHalf[i]<secondHalf[j]))){
|
||||
// Kopiere das aktuelle Element der ersten Hälfte in den ursprünglichen Vektor
|
||||
elems[begin+i+j] = firstHalf[i];
|
||||
i++;
|
||||
}else{
|
||||
// Kopiere das aktuelle Element der zweiten Hälfte in den ursprünglichen Vektor
|
||||
elems[begin+i+j] = secondHalf[j];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mergeSortHelp(std::vector<int>& elems, unsigned start, unsigned end){
|
||||
if(start==end||start==end-1){
|
||||
return;
|
||||
}
|
||||
unsigned mid = (start+end)/2;
|
||||
mergeSortHelp(elems, start, mid);
|
||||
mergeSortHelp(elems, mid, end);
|
||||
merge(elems, start, mid, end);
|
||||
}
|
||||
|
||||
void mergeSort(std::vector<int>& elems){
|
||||
mergeSortHelp(elems, 0, elems.size());
|
||||
}
|
||||
|
||||
int main(){
|
||||
std::vector<int> test = {1,4,2,67,3,76,13,8,10,22,6,9,5,11,32,0};
|
||||
hf::gebe_aus(test, 0, test.size());
|
||||
mergeSort(test);
|
||||
hf::gebe_aus(test, 0, test.size());
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
(a) Attribute und Hilfsmethoden sollen als private deklariert sein.
|
||||
Dies gewährleistet die Datenkapselung und Datenintegrität, indem sichergestellt wird, dass interne Zustände und Hilfsmethoden nicht direkt von außerhalb der Klasse modifiziert werden können.
|
||||
*/
|
||||
|
||||
class BeispielKlassePriPub
|
||||
{
|
||||
private:
|
||||
int attribut; // Privates Attribut
|
||||
|
||||
void hilfsMethode()
|
||||
{ // Private Hilfsmethode
|
||||
attribut *= 2;
|
||||
}
|
||||
|
||||
public:
|
||||
BeispielKlassePriPub() : attribut(5) {}
|
||||
|
||||
void offentlicheMethode()
|
||||
{
|
||||
hilfsMethode();
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
(b) Methoden, die public sind, sowie die Konstruktoren als auch der Destruktor sollen spezifiziert sein. (Hier müssen Sie keine Code-Beispiele angeben.)
|
||||
Dies bietet eine schriftliche Schnittstelle für andere um die Klasse richtig benutzen zu können.
|
||||
*/
|
||||
|
||||
/*
|
||||
(c) Das Signalwort const soll immer dort benutzt werden, wo es sinnvoll ist.
|
||||
Durch Verwendung von const können wir sicherstellen, dass eine Methode den internen Zustand des Objekts nicht ändert. Dies kann besonders hilfreich sein, wenn wir das Objekt in einer Situation verwenden möchten, in der es unverändert bleiben muss.
|
||||
*/
|
||||
|
||||
class BeispielKlasseConst
|
||||
{
|
||||
private:
|
||||
int attribut;
|
||||
|
||||
public:
|
||||
BeispielKlasseConst(int wert) : attribut(wert) {}
|
||||
|
||||
// Eine const Methode, die das Attribut nicht ändern kann
|
||||
int getAttribut() const
|
||||
{
|
||||
return attribut;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
(d) Jede Klasse, die mit new eigenen Speicher alloziert, soll einen Destruktor, einen Copy-Konstruktor und einen Copy-Assignment-Operator implementieren.
|
||||
Dies sind die großen vier in C++. Wenn eine dieser Operationen benötigt wird, werden wahrscheinlich alle benötigt werden. Sie helfen dabei, Speicherlecks zu verhindern und sicherzustellen, dass das Objekt korrekt kopiert wird.
|
||||
*/
|
||||
|
||||
class BeispielKlasse3
|
||||
{
|
||||
private:
|
||||
int *attribut;
|
||||
|
||||
public:
|
||||
// Konstruktor
|
||||
BeispielKlasse3(int wert) : attribut(new int(wert)) {}
|
||||
|
||||
// Destruktor
|
||||
~BeispielKlasse3()
|
||||
{
|
||||
delete attribut;
|
||||
}
|
||||
|
||||
// Kopierkonstruktor
|
||||
BeispielKlasse3(const BeispielKlasse3 &andere) : attribut(new int(*(andere.attribut))) {}
|
||||
|
||||
// Kopierzuweisungsoperator
|
||||
BeispielKlasse3 &operator=(const BeispielKlasse3 &andere)
|
||||
{
|
||||
if (this != &andere)
|
||||
{
|
||||
delete attribut;
|
||||
attribut = new int(*(andere.attribut));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
(e) Benutze Call-by-Reference in Verbindung mit const statt Call-by-Value, wenn das übergebene Objekt nicht verändert werden soll.
|
||||
Dies ist nützlich, um teure Kopien von großen Objekten zu vermeiden und gleichzeitig sicherzustellen, dass das ursprüngliche Objekt unverändert bleibt.
|
||||
*/
|
||||
|
||||
class AndereKlasse
|
||||
{
|
||||
// Definition für AndereKlasse
|
||||
};
|
||||
|
||||
class BeispielKlasse4
|
||||
{
|
||||
public:
|
||||
void irgendeineMethode(const AndereKlasse &objekt) const
|
||||
{
|
||||
// kann objekt hier verwenden, aber es nicht ändern
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
//g++ -std=c++14 -Wall -Wextra -Werror -pedantic ./w5/min.cpp -o ./bin/min && ./bin/min
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
int min(const std::vector<int>& vec);
|
||||
|
||||
int main() {
|
||||
std::vector<int> testVec = {10, 20, 2, 0, 30};
|
||||
std::cout << "The minimum value in the vector is: " << min(testVec) << std::endl;
|
||||
}
|
||||
|
||||
int min(const std::vector<int>& vec) {
|
||||
int minVal = vec[0];
|
||||
for (unsigned i = 1; i < vec.size(); ++i) {
|
||||
if (vec[i] < minVal) {
|
||||
minVal = vec[i];
|
||||
}
|
||||
}
|
||||
return minVal;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/* Informatik B - Sommersemester 2023
|
||||
Vorlesung am 28.04.2023
|
||||
Katharina Klost
|
||||
|
||||
Beispiele zu pairs
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
int main(){
|
||||
std::pair<std::string, int> mein_paar = {"Hallo", 1234};
|
||||
|
||||
std::cout << "Erster Eintrag vom mein_paar: " << mein_paar.first << std::endl;
|
||||
std::cout << "Zweiter Eintrag vom mein_paar: " << mein_paar.second << std::endl;
|
||||
|
||||
mein_paar.first = "Test";
|
||||
|
||||
std::cout << "Neuer erster Eintrag: " << mein_paar.first << std::endl;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
// g++ -std=c++14 -Wall -Wextra -Werror -pedantic ./w7/primitive_arrays.cpp -o ./bin/primitive_arrays && ./bin/primitive_arrays
|
||||
|
||||
#include <iostream>
|
||||
|
||||
/*
|
||||
Voraussetzungen:
|
||||
Die Funktion sollte nur aufgerufen werden, wenn eine Eingabe vom Benutzer erwartet wird.
|
||||
Es wird vorausgesetzt, dass der Benutzer ausschließlich positive Ganzzahlen eingibt.
|
||||
|
||||
Ergebnis:
|
||||
Die Funktion gibt die Summe aller vom Benutzer eingegebenen Zahlen als Integer zurück.
|
||||
|
||||
Effekt:
|
||||
Die Funktion reserviert und gibt dynamischen Speicher frei.
|
||||
*/
|
||||
|
||||
int summeZahlen()
|
||||
{
|
||||
int k;
|
||||
std::cout << "Geben Sie k an: ";
|
||||
std::cin >> k;
|
||||
|
||||
int *arr = new int[k];
|
||||
|
||||
for (int i = 0; i < k; ++i)
|
||||
{
|
||||
std::cout << "Geben Sie eine Zahl ein: ";
|
||||
std::cin >> arr[i];
|
||||
}
|
||||
|
||||
int summe = 0;
|
||||
for (int i = 0; i < k; ++i)
|
||||
{
|
||||
summe += arr[i];
|
||||
}
|
||||
|
||||
delete[] arr;
|
||||
|
||||
return summe;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int summe = summeZahlen();
|
||||
std::cout << "Die Summe ist: " << summe << std::endl;
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
#include <iostream>
|
||||
|
||||
// Definiere eine Vorlage für die Klasse QueueList.
|
||||
// Diese Klasse implementiert eine Warteschlange mit einer verketteten Liste.
|
||||
template <typename E>
|
||||
class QueueList
|
||||
{
|
||||
private:
|
||||
// Definition eines Knotens, der einen Wert und einen Zeiger auf den nächsten Knoten hat.
|
||||
struct Node
|
||||
{
|
||||
E value;
|
||||
Node *next;
|
||||
};
|
||||
|
||||
// Zeiger auf den Anfang und das Ende der Warteschlange und eine Zählvariable für die Größe.
|
||||
Node *head;
|
||||
Node *tail;
|
||||
int count;
|
||||
|
||||
public:
|
||||
// Konstruktor initialisiert Zeiger und Zähler mit Nullwerten.
|
||||
QueueList() : head(nullptr), tail(nullptr), count(0) {}
|
||||
|
||||
// Destruktor löscht alle Elemente in der Warteschlange.
|
||||
// Voraussetzung: keine
|
||||
// Effekt: Alle Elemente in der Warteschlange werden gelöscht
|
||||
// Ergebnis: Keines
|
||||
~QueueList()
|
||||
{
|
||||
while (!is_empty())
|
||||
{
|
||||
dequeue();
|
||||
}
|
||||
}
|
||||
|
||||
// Überprüft, ob die Warteschlange leer ist.
|
||||
// Voraussetzung: keine
|
||||
// Effekt: Keiner
|
||||
// Ergebnis: Wenn die Warteschlange leer ist, ist 'true' geliefert, sonst ist 'false' geliefert
|
||||
bool is_empty() const
|
||||
{
|
||||
return count == 0;
|
||||
}
|
||||
|
||||
// Gibt die Größe der Warteschlange zurück.
|
||||
// Voraussetzung: keine
|
||||
// Effekt: Keiner
|
||||
// Ergebnis: Die Anzahl der Elemente in der Warteschlange wird zurückgegeben
|
||||
unsigned size() const
|
||||
{
|
||||
return count;
|
||||
}
|
||||
|
||||
// Gibt das erste Element der Warteschlange zurück.
|
||||
// Voraussetzung: Die Warteschlange ist nicht leer
|
||||
// Effekt: Keiner
|
||||
// Ergebnis: Das vorderste Element wird zurückgegeben
|
||||
E front() const
|
||||
{
|
||||
if (is_empty())
|
||||
{
|
||||
throw std::runtime_error("Queue is empty");
|
||||
}
|
||||
return this->head->value;
|
||||
}
|
||||
|
||||
// Fügt ein Element am Ende der Warteschlange ein.
|
||||
// Voraussetzung: Keine
|
||||
// Effekt: Das übergebene Element wird hinten in die Warteschlange eingefügt
|
||||
// Ergebnis: Keines
|
||||
void enqueue(E x)
|
||||
{
|
||||
Node *newNode = new Node();
|
||||
newNode->value = x;
|
||||
newNode->next = nullptr;
|
||||
|
||||
if (tail != nullptr)
|
||||
{
|
||||
tail->next = newNode;
|
||||
}
|
||||
|
||||
tail = newNode;
|
||||
|
||||
if (is_empty())
|
||||
{
|
||||
head = newNode;
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
// Entfernt das erste Element der Warteschlange und gibt seinen Wert zurück.
|
||||
// Voraussetzung: Die Warteschlange ist nicht leer
|
||||
// Effekt: Das vorderste Element wird aus der Warteschlange entfernt
|
||||
// Ergebnis: Das vorderste Element wird zurückgegeben
|
||||
E dequeue()
|
||||
{
|
||||
if (is_empty())
|
||||
{
|
||||
throw std::runtime_error("Queue is empty");
|
||||
}
|
||||
|
||||
Node *tempNode = head;
|
||||
E value = head->value;
|
||||
|
||||
head = head->next;
|
||||
|
||||
if (head == nullptr)
|
||||
{
|
||||
tail = nullptr;
|
||||
}
|
||||
|
||||
delete tempNode;
|
||||
count--;
|
||||
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
// Erstellt eine Warteschlange und fügt die Werte 3, 5 und 2 hinzu. Dann wird das vorderste Element angezeigt und zwei Elemente werden entfernt.
|
||||
// Überprüft schließlich, ob die Warteschlange leer ist.
|
||||
QueueList<int> q;
|
||||
q.enqueue(1);
|
||||
q.enqueue(2);
|
||||
q.enqueue(3);
|
||||
std::cout << q.front() << std::endl; // Erwartetes Ergebnis: 1
|
||||
std::cout << q.dequeue() << std::endl; // Erwartetes Ergebnis: 1
|
||||
std::cout << q.dequeue() << std::endl; // Erwartetes Ergebnis: 2
|
||||
std::cout << q.is_empty() << std::endl; // Erwartetes Ergebnis: 0
|
||||
std::cout << std::endl;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/* Informatik B - Sommersemester 2023
|
||||
Vorlesung am 03.05.2023
|
||||
Katharina Klost
|
||||
|
||||
Beispiele zu rekursion und iteration
|
||||
*/
|
||||
#include <iostream>
|
||||
|
||||
/*
|
||||
Voraussetzung: keine
|
||||
Ergebnis: Die Fakultät von n ist geliefert
|
||||
Effekt: keiner
|
||||
Rekursive Implementierung
|
||||
*/
|
||||
unsigned fak_rek(unsigned n);
|
||||
|
||||
|
||||
/*
|
||||
Voraussetzung: keine
|
||||
Ergebnis: Die Fakultät von n ist geliefert
|
||||
Effekt: keiner
|
||||
Iterative Implementierung
|
||||
*/
|
||||
unsigned fak_iter(unsigned n);
|
||||
|
||||
//Da hier direkte rekursion verwendet wird, gibt es keine Optimierung.
|
||||
// Bei Endrekursion und Verwendung des -O3 flags wird die Endrekursion optimiert
|
||||
unsigned fak_rek(unsigned n){
|
||||
if (n==0){
|
||||
return 1;
|
||||
}
|
||||
return(fak_rek(n-1)*n);
|
||||
}
|
||||
|
||||
unsigned fak_iter(unsigned n){
|
||||
unsigned res = 1;
|
||||
for (unsigned i = 1; i<=n; i++){
|
||||
res*=i;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int main(){
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
/*
|
||||
- Voraussetzungen: str ist ein String, charToReplace und replacementChar sind Zeichen
|
||||
- Ergebnis: str ist ein String, in dem alle Vorkommen von charToReplace durch replacementChar ersetzt wurden
|
||||
- Seiteneffekte: keine
|
||||
|
||||
Der Rückgabetyp ist string, weil wir einen neuen String zurückgeben wollen, in dem alle Vorkommen von charToReplace durch replacementChar ersetzt wurden.
|
||||
Die Parameter sind char, weil wir nur ein Zeichen ersetzen wollen.
|
||||
|
||||
*/
|
||||
std::string repl(std::string str, char charToReplace, char replacementChar);
|
||||
|
||||
int main() {
|
||||
|
||||
std::cout << "Bitte gebe einen String ein bei dem du die Zeichen ersetzen willst: ";
|
||||
std::string s;
|
||||
std::getline(std::cin, s);
|
||||
|
||||
std::cout << "Bitte gebe das Zeichen ein, welches zu ersetzen möchtest: ";
|
||||
char a;
|
||||
std::cin >> a;
|
||||
|
||||
std::cout << "Bitte gebe das Zeichen ein, durch welches du ersetzen möchtest: ";
|
||||
char b;
|
||||
std::cin >> b;
|
||||
|
||||
std::cout << "Dein neuer String ist: " << repl(s, a, b) << std::endl;
|
||||
|
||||
}
|
||||
|
||||
std::string repl(std::string str, char charToReplace, char replacementChar) {
|
||||
|
||||
for (unsigned i = 0; i < str.length(); i++) {
|
||||
if (str[i] == charToReplace) {
|
||||
str[i] = replacementChar;
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
std::vector<int> reverseSortVector(std::vector<int> vec);
|
||||
|
||||
int main() {
|
||||
|
||||
int input = -1;
|
||||
std::vector<int> vec;
|
||||
std::vector<int> vecnew;
|
||||
|
||||
std::cout << "Geben Sie eine Zahlenfolge ein, mit 0 beenden Sie die Eingabe: " << std::endl;
|
||||
while (input != 0) {
|
||||
std::cin >> input;
|
||||
if (input != 0) {
|
||||
vec.push_back(input);
|
||||
}
|
||||
}
|
||||
|
||||
vecnew = reverseSortVector(vec);
|
||||
|
||||
std::cout << "Die Zahlenfolge in umgekehrter Reihenfolge: " << std::endl;
|
||||
for (unsigned i = 0; i < vecnew.size(); i++) {
|
||||
std::cout << vecnew[i] << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::vector<int> reverseSortVector(std::vector<int> vec) {
|
||||
std::vector<int> vecnew;
|
||||
for (unsigned i = vec.size() - 1; i >= 0; i--) {
|
||||
vecnew.push_back(vec[i]);
|
||||
}
|
||||
return vecnew;
|
||||
}
|
||||
Executable
+81
@@ -0,0 +1,81 @@
|
||||
// g++ -std=c++14 -Wall -Wextra -Werror -pedantic ./w4/rucksack2.cpp -o
|
||||
// ./bin/rucksack2
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
struct Gegenstand {
|
||||
int gewicht;
|
||||
int wert;
|
||||
|
||||
Gegenstand(int g, int w) : gewicht(g), wert(w) {}
|
||||
};
|
||||
|
||||
int rucksackWert(const std::vector<Gegenstand> &gegenstaende, int kapazitaet,
|
||||
int index) {
|
||||
if (index < 0 || kapazitaet == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (gegenstaende[index].gewicht > kapazitaet) {
|
||||
return rucksackWert(gegenstaende, kapazitaet, index - 1);
|
||||
} else {
|
||||
int wert1 = rucksackWert(gegenstaende, kapazitaet, index - 1);
|
||||
int wert2 =
|
||||
gegenstaende[index].wert +
|
||||
rucksackWert(gegenstaende, kapazitaet - gegenstaende[index].gewicht,
|
||||
index - 1);
|
||||
return (wert1 > wert2) ? wert1 : wert2;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Gegenstand>
|
||||
rucksackGegenstaende(const std::vector<Gegenstand> &gegenstaende,
|
||||
int kapazitaet, int index) {
|
||||
if (index < 0 || kapazitaet == 0) {
|
||||
return std::vector<Gegenstand>();
|
||||
}
|
||||
|
||||
if (gegenstaende[index].gewicht > kapazitaet) {
|
||||
return rucksackGegenstaende(gegenstaende, kapazitaet, index - 1);
|
||||
} else {
|
||||
int wert1 = rucksackWert(gegenstaende, kapazitaet, index - 1);
|
||||
int wert2 =
|
||||
gegenstaende[index].wert +
|
||||
rucksackWert(gegenstaende, kapazitaet - gegenstaende[index].gewicht,
|
||||
index - 1);
|
||||
|
||||
if (wert1 > wert2) {
|
||||
return rucksackGegenstaende(gegenstaende, kapazitaet, index - 1);
|
||||
} else {
|
||||
std::vector<Gegenstand> ausgewaehlteGegenstaende = rucksackGegenstaende(
|
||||
gegenstaende, kapazitaet - gegenstaende[index].gewicht, index - 1);
|
||||
ausgewaehlteGegenstaende.push_back(gegenstaende[index]);
|
||||
return ausgewaehlteGegenstaende;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::vector<Gegenstand> gegenstaende;
|
||||
gegenstaende.push_back(Gegenstand(2, 10));
|
||||
gegenstaende.push_back(Gegenstand(3, 15));
|
||||
gegenstaende.push_back(Gegenstand(5, 20));
|
||||
gegenstaende.push_back(Gegenstand(7, 25));
|
||||
|
||||
int kapazitaet = 10;
|
||||
|
||||
int optimalerWert =
|
||||
rucksackWert(gegenstaende, kapazitaet, gegenstaende.size() - 1);
|
||||
std::cout << "Optimaler Wert: " << optimalerWert << std::endl;
|
||||
|
||||
std::vector<Gegenstand> optimaleGegenstaende =
|
||||
rucksackGegenstaende(gegenstaende, kapazitaet, gegenstaende.size() - 1);
|
||||
std::cout << "Optimale Gegenstände: ";
|
||||
for (const auto &gegenstand : optimaleGegenstaende) {
|
||||
std::cout << "(" << gegenstand.gewicht << ", " << gegenstand.wert << ") ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
g++ -std=c++14 -Wall -Wextra -Werror -pedantic ./w4/hilfsfunktionen.cpp ./w4/selectionsort.cpp -o ./bin/selectionsort
|
||||
|
||||
Dieser Algorithmus durchläuft das Array und findet das kleinste Element, dann tauscht es dieses Element mit dem ersten Element des Arrays.
|
||||
Danach durchläuft es den restlichen Teil des Arrays, findet das kleinste Element und tauscht es mit dem zweiten Element des Arrays.
|
||||
Dieser Prozess wird so lange wiederholt, bis das gesamte Array sortiert ist. Im Hauptprogramm (main) wird der Selection Sort Algorithmus auf
|
||||
ein Testarray angewendet und das Array vor und nach der Sortierung ausgegeben.
|
||||
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
#include "hilfsfunktionen.hpp"
|
||||
|
||||
void selectionSort(std::vector<int>& elems){
|
||||
for(unsigned i = 0; i < elems.size();i++){
|
||||
hf::swap(elems, i, hf::minimumIndex(elems, i, elems.size()));
|
||||
}
|
||||
}
|
||||
|
||||
int main(){
|
||||
std::vector<int> test = {1,4,2,67,3,76,13,8,10,22,6,9,5,11,32,0};
|
||||
hf::gebe_aus(test, 0, test.size());
|
||||
selectionSort(test);
|
||||
hf::gebe_aus(test, 0, test.size());
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/* Informatik B - Sommersemester 2023
|
||||
Vorlesung am 28.04.2023
|
||||
Katharina Klost
|
||||
|
||||
Beispiele zu Strings
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
int main(){
|
||||
std::string ein_string = "Hallo";
|
||||
char stelle2 = ein_string[2];
|
||||
std::cout << "An index 2 steht: " << stelle2 << std::endl;
|
||||
ein_string[2]= 'x';
|
||||
std::cout << "Stelle 2 verändert: " << ein_string << std::endl;
|
||||
ein_string = ein_string + " Welt!";
|
||||
std::cout << ein_string << std::endl;
|
||||
std::cout << ein_string + 'c' << std::endl;
|
||||
|
||||
std::cout << "Der String \"" << ein_string << "\" hat " << ein_string.length() << " Zeichen" << std::endl;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/* Informatik B - Sommersemester 2023
|
||||
Vorlesung am 28.04.2023
|
||||
Katharina Klost
|
||||
|
||||
Beispiele zu structs
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
|
||||
struct studi{
|
||||
std::string name;
|
||||
int matrikelnummer;
|
||||
bool bachelor;
|
||||
std::string studienfach;
|
||||
};
|
||||
|
||||
struct studi2{
|
||||
std::string name;
|
||||
int matrikelnummer;
|
||||
bool bachelor;
|
||||
std::string studienfach;
|
||||
};
|
||||
|
||||
int main(){
|
||||
studi luca = {"Luca Muster", 42, true, "Informatik"};
|
||||
studi mo = {"Mo", 112, true, "Bioinformatik"};
|
||||
studi alex = {"Alex Müller", 4711, false, "Informatik"};
|
||||
|
||||
//mit dem . kann auf ein Feld zugegriffen werden.
|
||||
std::cout << mo.name << std::endl;
|
||||
mo.bachelor = false;
|
||||
std::cout << mo.bachelor << std::endl;
|
||||
|
||||
// wegen der Wertsemantik werden die Einträge beim zuweisen kopiert
|
||||
studi luca2 = luca;
|
||||
|
||||
luca2.name = "Luca Mustermann";
|
||||
std::cout << luca2.name << std::endl;
|
||||
std::cout << luca.name << std::endl;
|
||||
studi2 luca3;
|
||||
//nur structs vom gleichen Typ können einander zugewiesen werden
|
||||
//luca3 = luca;
|
||||
|
||||
//structs können auch in vectoren gespeichert werden
|
||||
std::vector<studi> tutorium ={luca,mo};
|
||||
tutorium.push_back(alex);
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
template <typename SchluesselTyp, typename WertTyp>
|
||||
class schluesselWertPaar
|
||||
{
|
||||
private:
|
||||
SchluesselTyp schluessel;
|
||||
WertTyp wert;
|
||||
|
||||
public:
|
||||
schluesselWertPaar() {}
|
||||
// Konstruktor
|
||||
schluesselWertPaar(SchluesselTyp schluessel, WertTyp wert) : schluessel(schluessel), wert(wert) {}
|
||||
|
||||
// Getter für Schlüssel und Wert
|
||||
SchluesselTyp getSchluessel() const
|
||||
{
|
||||
return schluessel;
|
||||
}
|
||||
|
||||
WertTyp getWert() const
|
||||
{
|
||||
return wert;
|
||||
}
|
||||
|
||||
// Setter für Schlüssel und Wert
|
||||
void setSchluessel(SchluesselTyp neuerSchluessel)
|
||||
{
|
||||
schluessel = neuerSchluessel;
|
||||
}
|
||||
|
||||
void setWert(WertTyp neuerWert)
|
||||
{
|
||||
wert = neuerWert;
|
||||
}
|
||||
|
||||
// Überladen des < Operators
|
||||
bool operator<(const schluesselWertPaar &paar) const
|
||||
{
|
||||
return schluessel < paar.getSchluessel();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename SchluesselTyp, typename WertTyp>
|
||||
void merge(std::vector<schluesselWertPaar<SchluesselTyp, WertTyp>> &vec, int start, int mid, int end)
|
||||
{
|
||||
int i, j, k;
|
||||
int n1 = mid - start + 1;
|
||||
int n2 = end - mid;
|
||||
|
||||
std::vector<schluesselWertPaar<SchluesselTyp, WertTyp>> left(n1), right(n2);
|
||||
|
||||
for (i = 0; i < n1; i++)
|
||||
left[i] = vec[start + i];
|
||||
for (j = 0; j < n2; j++)
|
||||
right[j] = vec[mid + 1 + j];
|
||||
|
||||
i = 0;
|
||||
j = 0;
|
||||
k = start;
|
||||
while (i < n1 && j < n2)
|
||||
{
|
||||
if (left[i] < right[j])
|
||||
{
|
||||
vec[k] = left[i];
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
vec[k] = right[j];
|
||||
j++;
|
||||
}
|
||||
k++;
|
||||
}
|
||||
|
||||
while (i < n1)
|
||||
{
|
||||
vec[k] = left[i];
|
||||
i++;
|
||||
k++;
|
||||
}
|
||||
|
||||
while (j < n2)
|
||||
{
|
||||
vec[k] = right[j];
|
||||
j++;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename SchluesselTyp, typename WertTyp>
|
||||
void mergeSort(std::vector<schluesselWertPaar<SchluesselTyp, WertTyp>> &vec, int start, int end)
|
||||
{
|
||||
if (start < end)
|
||||
{
|
||||
int mid = start + (end - start) / 2;
|
||||
|
||||
mergeSort(vec, start, mid);
|
||||
mergeSort(vec, mid + 1, end);
|
||||
|
||||
merge(vec, start, mid, end);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename SchluesselTyp, typename WertTyp>
|
||||
int binarySearch(std::vector<schluesselWertPaar<SchluesselTyp, WertTyp>> &vec, int start, int end, SchluesselTyp key)
|
||||
{
|
||||
if (end >= start)
|
||||
{
|
||||
int mid = start + (end - start) / 2;
|
||||
|
||||
if (vec[mid].getSchluessel() == key)
|
||||
return mid;
|
||||
|
||||
if (vec[mid].getSchluessel() > key)
|
||||
return binarySearch(vec, start, mid - 1, key);
|
||||
|
||||
return binarySearch(vec, mid + 1, end, key);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
std::vector<schluesselWertPaar<int, std::string>> vec;
|
||||
vec.push_back(schluesselWertPaar<int, std::string>(3, "drei"));
|
||||
vec.push_back(schluesselWertPaar<int, std::string>(1, "eins"));
|
||||
vec.push_back(schluesselWertPaar<int, std::string>(2, "zwei"));
|
||||
std::cout << "Vor dem sortieren:\n";
|
||||
|
||||
for (const auto &paar : vec)
|
||||
{
|
||||
std::cout << paar.getSchluessel() << " " << paar.getWert() << std::endl;
|
||||
}
|
||||
|
||||
mergeSort(vec, 0, vec.size() - 1);
|
||||
|
||||
std::cout << "Nach dem sortieren:\n";
|
||||
|
||||
for (const auto &paar : vec)
|
||||
{
|
||||
std::cout << paar.getSchluessel() << " " << paar.getWert() << std::endl;
|
||||
}
|
||||
|
||||
int index = binarySearch(vec, 0, vec.size() - 1, 3);
|
||||
|
||||
if (index != -1)
|
||||
{
|
||||
std::cout << "Gefunden an Position: " << index + 1 << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Nicht gefunden" << std::endl;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
clear && g++ -std=c++14 -Wall -Wextra -Werror -pedantic ./w5/turn_min.cpp -o ./bin/turn_min && ./bin/turn_min
|
||||
|
||||
Bei jedem Durchlauf halbieren wir die Größe der Eingabe (also n/2),
|
||||
und wir müssen alle Elemente betrachten, um das Minimum zu finden (also O(n))
|
||||
Daraus folgt die Rekursionsgleichung: T(n) = T(n/2) + O(n)
|
||||
|
||||
Da wir log(n) Runden benötigen und in jeder Runde O(n) Operationen durchführen
|
||||
beträgt die Gesamtlaufzeit des Algorithmus O(n log n)
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
std::pair<int, int> TurnMin(std::vector<int>& vec);
|
||||
|
||||
int main() {
|
||||
std::vector<int> vec = {7, 3, 2, 5, 10, -5, 4, 6,2,2,3,4,4,5,6,76,7,78};
|
||||
auto ergebnis = TurnMin(vec);
|
||||
std::cout << "Die Gewinnerzahl, nach " << ergebnis.first << " Runden, ist: " << ergebnis.second << std::endl;
|
||||
}
|
||||
|
||||
std::pair<int, int> TurnMin(std::vector<int>& vec) {
|
||||
int runde = 0;
|
||||
while (vec.size() > 1) {
|
||||
std::vector<int> gewinner;
|
||||
for (unsigned i = 0; i < vec.size(); i += 2) {
|
||||
if (vec[i] < vec[i + 1]) {
|
||||
gewinner.push_back(vec[i]);
|
||||
}
|
||||
else {
|
||||
gewinner.push_back(vec[i + 1]);
|
||||
}
|
||||
}
|
||||
vec = gewinner;
|
||||
runde++;
|
||||
}
|
||||
return {runde, vec[0]};
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
int main() {
|
||||
|
||||
// Aufgabe 1a
|
||||
|
||||
int x;
|
||||
std::cin >> x;
|
||||
int y = 1;
|
||||
|
||||
for (int i = x; i > 0; i--) {
|
||||
y = y * i;
|
||||
}
|
||||
|
||||
std::cout << y << std::endl;
|
||||
|
||||
// Aufgabe 1b
|
||||
|
||||
int z = 1;
|
||||
int l = x;
|
||||
while (l > 1) {
|
||||
z = z * l;
|
||||
l--;
|
||||
}
|
||||
|
||||
std::cout << z << std::endl;
|
||||
|
||||
// Aufgabe 2
|
||||
|
||||
// 1 Load 7
|
||||
// 2 Write 6
|
||||
// 3 Add 7
|
||||
// 4 Jump 2
|
||||
// 5 Return
|
||||
// 6 0
|
||||
// 7 3
|
||||
|
||||
// Aufgabe 3
|
||||
|
||||
std::string artist;
|
||||
std::cout << "Wer ist dein Lieblingsartist?" << std::endl;
|
||||
std::cin >> artist;
|
||||
std::cout << "Dein Lieblingsartist ist " << artist << std::endl;
|
||||
|
||||
std::string album;
|
||||
std::cout << "Was ist dein Lieblingsalbum?" << std::endl;
|
||||
std::cin >> album;
|
||||
std::cout << "Dein Lieblingsalbum ist " << album << std::endl;
|
||||
|
||||
int zahl;
|
||||
std::cout << "Was ist deine Lieblingszahl?" << std::endl;
|
||||
std::cin >> zahl;
|
||||
int quad = zahl * zahl;
|
||||
std::cout << "Deine Lieblingszahl ist " << quad << std::endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/* Informatik B - Sommersemester 2023
|
||||
Vorlesung am 26.04.2023
|
||||
Katharina Klost
|
||||
|
||||
Beispiele zur Ein-und Ausgabe
|
||||
*/
|
||||
|
||||
#include <iostream> // gibt Ein-und Ausgabe
|
||||
#include <climits> // gibt Minimal- und Maximalwerte für die Datentypen
|
||||
|
||||
int main(){
|
||||
|
||||
/*Zuweisen einer Gleitkommazahl zu einer Ganzzahl schneidet die
|
||||
Nachkommastellen ab
|
||||
*/
|
||||
int a = 3.5;
|
||||
std::cout << "a: " << a << std::endl;
|
||||
|
||||
int n1 = SHRT_MAX;
|
||||
short n2 = SHRT_MAX;
|
||||
|
||||
|
||||
short n3 = n2 + n2; // overflow
|
||||
int n4 = n1 + n2; //der größere Datentyp gewinnt
|
||||
|
||||
std::cout << "n3, n4: "<<n3 << ", " << n4<< std::endl;
|
||||
|
||||
|
||||
unsigned int n5 = 5;
|
||||
int n6 = -6;
|
||||
// Bei Kombination von unsigned und signed Typen gewinnt
|
||||
// der unsigned, der Inhalt der Speicherzelle wird dann
|
||||
// intern anders interpretiert
|
||||
std::cout << "n5+n6: "<< n5+6 <<std::endl;
|
||||
|
||||
|
||||
|
||||
// Bei der Kombination von Gleitkommazahlen und Ganzzahlen gewinnt
|
||||
// die Gleitkommazahl
|
||||
double f1 = 0.4;
|
||||
std::cout << f1 + n6<< std::endl;
|
||||
|
||||
|
||||
int i1 = 18;
|
||||
int i2 = 16;
|
||||
|
||||
//implizieter Typcast, es wird erst Ganzzahlig dividiert
|
||||
// (Nachkommastellen abgeschnitten) und dann umgewandelt
|
||||
double dv1 = i1 / i2;
|
||||
|
||||
//werden Divisor und Divident erst umgewandelt, ist das Ergebnis die
|
||||
//erwartete Gleitkommazahl
|
||||
double dv2 = static_cast<double>(i1) / static_cast<double>(i2);
|
||||
|
||||
// Wie weiter oben, erst wird geteilt (und abgeschnitten) und dann umgewandelt
|
||||
// und dann zugewiesen.
|
||||
double dv3 = static_cast<double>( i1 / i2 );
|
||||
std::cout << dv1 << ", " << dv2 << ", " << dv3 << std::endl;
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
int main() {
|
||||
|
||||
// 1.
|
||||
|
||||
int eingabe0 = -1;
|
||||
|
||||
std::cout << "Aufgabe (1) oder (2)?" << std::endl;
|
||||
std::cin >> eingabe0;
|
||||
|
||||
if (eingabe0 == 1){
|
||||
int eingabe1 = -1;
|
||||
std::vector<int> zahlenfolge;
|
||||
int min = 0;
|
||||
int max = 0;
|
||||
|
||||
while (true) {
|
||||
|
||||
|
||||
std::cout << "Geben Sie eine Zahl der Zahlenfolge ein, mit 0 geben sie MIN und MAX aus, mit 9999 geben sie den Mittelwert aus: " << std::endl;
|
||||
std::cin >> eingabe1;
|
||||
|
||||
if (eingabe1 == 0) {
|
||||
|
||||
for (unsigned i = 0; i < zahlenfolge.size(); i++){
|
||||
|
||||
if (zahlenfolge[i] < min){
|
||||
min = zahlenfolge[i];
|
||||
}
|
||||
|
||||
if (zahlenfolge[i] > max){
|
||||
max = zahlenfolge[i];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::cout << "Das Maximum der Zahlenfolge ist: " << max << std::endl;
|
||||
std::cout << "Das Minimum der Zahlenfolge ist: " << min << std::endl;
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (eingabe1 == 9999) {
|
||||
|
||||
float summe = 0;
|
||||
|
||||
for (unsigned i = 0; i < zahlenfolge.size(); i++){
|
||||
summe += zahlenfolge[i];
|
||||
}
|
||||
|
||||
double mittelwert = summe / zahlenfolge.size();
|
||||
|
||||
std::cout << "Der Mittelwert der Zahlenfolge ist: " << mittelwert << std::endl;
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
zahlenfolge.push_back(eingabe1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// 2.
|
||||
|
||||
if (eingabe0 == 2){
|
||||
|
||||
|
||||
char eingabe01;
|
||||
std::cout << "Teilaufgabe (a) oder (b) ?" << std::endl;
|
||||
std::cin >> eingabe01;
|
||||
|
||||
// 2 a)
|
||||
if (eingabe01 == 'a'){
|
||||
|
||||
int eingabe2 = -1;
|
||||
std::cout << "Geben Sie eine Zahl größer 0 ein, von der die Quersumme berechnet werden soll" << std::endl;
|
||||
std::cin >> eingabe2;
|
||||
|
||||
int eingabe3 = -1;
|
||||
std::cout << "Soll die Quersumme mit einer while (0) oder for (1) Schleife berechnet werden?" << std::endl;
|
||||
std::cin >> eingabe3;
|
||||
|
||||
if (eingabe3 == 0){
|
||||
|
||||
int quersummewhile = 0;
|
||||
|
||||
while (eingabe2 > 0){
|
||||
quersummewhile += eingabe2 % 10;
|
||||
eingabe2 /= 10;
|
||||
}
|
||||
|
||||
std::cout << "Die Quersumme der Zahl ist: " << quersummewhile << std::endl;
|
||||
|
||||
}
|
||||
|
||||
if (eingabe3 == 1){
|
||||
|
||||
int quersummefor = 0;
|
||||
|
||||
for (quersummefor; eingabe2 > 0; eingabe2 /= 10){
|
||||
quersummefor += eingabe2 % 10;
|
||||
}
|
||||
|
||||
std::cout << "Die Quersumme der Zahl ist: " << quersummefor << std::endl;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 2 b)
|
||||
if (eingabe01 == 'b'){
|
||||
int n;
|
||||
std::cout << "Geben Sie eine Zahl größer 0 ein: " << std::endl;
|
||||
std::cin >> n;
|
||||
|
||||
for (int i = 0; i <= n; i++) {
|
||||
std::string output = "";
|
||||
if (i % 3 == 0) {
|
||||
std::cout << "bli" << std::endl;
|
||||
}
|
||||
if (i % 5 == 0) {
|
||||
std::cout << "bla" << std::endl;
|
||||
}
|
||||
if (i % 7 == 0) {
|
||||
std::cout << "blub" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
/* Informatik B - Sommersemester 2022
|
||||
Übung 06
|
||||
Katharina Klost
|
||||
|
||||
Aufgabe zu Pointern
|
||||
|
||||
g++ -std=c++14 -Wall -Wextra -Werror -pedantic ./w7/ueb7pointer.cpp -o ./bin/ueb7pointer && ./bin/ueb7pointer
|
||||
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
void ref(int &alpha)
|
||||
{ // Call-by-Reference
|
||||
std::cout << "&alpha: " << (&alpha) << std::endl;
|
||||
std::cout << "alpha: " << (alpha) << std::endl;
|
||||
alpha++;
|
||||
}
|
||||
|
||||
void val(int alpha)
|
||||
{ // Call-by-Value
|
||||
std::cout << "&alpha: " << (&alpha) << std::endl;
|
||||
std::cout << "alpha: " << (alpha) << std::endl;
|
||||
alpha++;
|
||||
}
|
||||
|
||||
void func1(int *alpha)
|
||||
{
|
||||
std::cout << "&alpha: " << (&alpha) << std::endl;
|
||||
std::cout << "alpha: " << (alpha) << std::endl;
|
||||
alpha++;
|
||||
}
|
||||
|
||||
void func2(int *alpha)
|
||||
{
|
||||
std::cout << "&alpha: " << (&alpha) << std::endl;
|
||||
std::cout << "alpha: " << (alpha) << std::endl;
|
||||
(*alpha)++;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
// Zeichnen Sie Speicherbilder, die veranschaulichen Sie was hier passiert.
|
||||
// Erklären Sie die entsprechenden Ausgaben.
|
||||
|
||||
int a = 42;
|
||||
int b = 6;
|
||||
int *c = &a;
|
||||
int *d = &b;
|
||||
int &e = a;
|
||||
|
||||
std::cout << "a: " << a << std::endl;
|
||||
std::cout << "b: " << b << std::endl;
|
||||
std::cout << "c: " << c << std::endl;
|
||||
std::cout << "d: " << d << std::endl;
|
||||
std::cout << "e: " << e << std::endl;
|
||||
std::cout << std::endl;
|
||||
std::cout << "&a: " << (&a) << std::endl;
|
||||
std::cout << "&b: " << (&b) << std::endl;
|
||||
std::cout << "&c: " << (&c) << std::endl;
|
||||
std::cout << "&d: " << (&d) << std::endl;
|
||||
std::cout << "&e: " << (&e) << std::endl;
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
// std::cout << (*a) << std::endl; Warum geht das nicht?
|
||||
// std::cout << (*e) << std::endl; Warum geht das nicht?
|
||||
|
||||
std::cout << "*c: " << (*c) << std::endl;
|
||||
std::cout << "*d: " << (*d) << std::endl;
|
||||
std::cout << std::endl;
|
||||
std::cout << "=== Skizzieren Sie den Aufbau des Speichers zu diesem Zeitpunkt ===" << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
a = *c * *d;
|
||||
std::cout << "a: " << a << std::endl;
|
||||
*d -= 3;
|
||||
std::cout << "*d: " << (*d) << std::endl;
|
||||
b = a * b;
|
||||
std::cout << "b: " << b << std::endl;
|
||||
c = d;
|
||||
std::cout << "*c: " << (*c) << std::endl;
|
||||
|
||||
std::cout << std::endl;
|
||||
std::cout << "=== Skizzieren Sie den Aufbau des Speichers zu diesem Zeitpunkt ===" << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
b = 7;
|
||||
std::cout << "b: " << b << std::endl;
|
||||
a = *c + *d;
|
||||
std::cout << "a: " << a << std::endl;
|
||||
std::cout << "&e: " << (&e) << std::endl;
|
||||
std::cout << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
c = &a;
|
||||
|
||||
std::cout << std::endl;
|
||||
std::cout << "=== Skizzieren Sie den Aufbau des Speichers zu diesem Zeitpunkt ===" << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << std::endl;
|
||||
std::cout << "== Erklären Sie die folgenden Ausgaben ==" << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "a: " << a << std::endl;
|
||||
std::cout << "&a: " << (&a) << std::endl;
|
||||
std::cout << "Rufe ref(a) auf" << std::endl;
|
||||
ref(a);
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "a: " << a << std::endl;
|
||||
std::cout << "&a: " << (&a) << std::endl;
|
||||
std::cout << "Rufe val(a) auf" << std::endl;
|
||||
val(a);
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "a: " << a << std::endl;
|
||||
|
||||
std::cout << "c: " << c << std::endl;
|
||||
std::cout << "&c: " << (&c) << std::endl;
|
||||
std::cout << "Rufe func1(c) auf" << std::endl;
|
||||
func1(c);
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "c: " << c << std::endl;
|
||||
std::cout << "&c: " << (&c) << std::endl;
|
||||
|
||||
std::cout << "Rufe func2(c) auf" << std::endl;
|
||||
func2(c);
|
||||
std::cout << "c: " << c << std::endl;
|
||||
std::cout << "&c: " << (&c) << std::endl;
|
||||
std::cout << "a: " << a << std::endl;
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
// clear && g++ -std=c++14 -Wall -Wextra -Werror -pedantic ./w5/hilfsfunktionen.cpp ./w5/ultrasort.cpp -o ./bin/ultrasort && ./bin/ultrasort
|
||||
|
||||
#include "hilfsfunktionen.hpp"
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
|
||||
bool isSorted(const std::vector<int>& vec);
|
||||
void insertionSort(std::vector<int>& elems);
|
||||
void merge(std::vector<int>& first_part, std::vector<int>& second_part, std::vector<int>& elems);
|
||||
void ultraSort(std::vector<int>& elems);
|
||||
void ultraSortParam(std::vector<int>& elems, double k);
|
||||
|
||||
int main() {
|
||||
|
||||
srand(time(NULL));
|
||||
double time;
|
||||
std::vector<int> array;
|
||||
|
||||
// Runtime (a)
|
||||
std::cout << "############ RUNTIME (ultraSort) ############ \n";
|
||||
for (int size = 10000; size <= 100000; size *= 10) {
|
||||
std::cout << " " << size << " Elemente:" << std::endl;
|
||||
|
||||
array = hf::zufalls_array(size);
|
||||
|
||||
time = clock();
|
||||
ultraSort(array);
|
||||
time = clock() - time;
|
||||
|
||||
std::cout << " Zufällig: " << (time/CLOCKS_PER_SEC) << " Sekunden" << std::endl;
|
||||
|
||||
array = hf::sortiertes_array(size, true);
|
||||
|
||||
time = clock();
|
||||
ultraSort(array);
|
||||
time = clock() - time;
|
||||
|
||||
std::cout << " Aufsteigend: " << (time/CLOCKS_PER_SEC) << " Sekunden" << std::endl;
|
||||
|
||||
array = hf::sortiertes_array(size, false);
|
||||
|
||||
time = clock();
|
||||
ultraSort(array);
|
||||
time = clock() - time;
|
||||
|
||||
std::cout << " Absteigend: " << (time/CLOCKS_PER_SEC) << " Sekunden" << std::endl;
|
||||
|
||||
if (isSorted(array)) {
|
||||
std::cout << " Array is sorted.\n";
|
||||
} else {
|
||||
std::cout << " Array is not sorted.\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Optimal k
|
||||
std::cout << "############ OPTIMAL K ############ \n";
|
||||
std::vector<double> k_values = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9};
|
||||
double optimal_k = 0;
|
||||
double shortest_time = std::numeric_limits<double>::max();
|
||||
for (double k : k_values) {
|
||||
|
||||
array = hf::zufalls_array(10000);
|
||||
time = clock();
|
||||
ultraSortParam(array, k);
|
||||
time = clock() - time;
|
||||
|
||||
if (time < shortest_time) {
|
||||
shortest_time = time;
|
||||
optimal_k = k;
|
||||
}
|
||||
}
|
||||
std::cout << " Optimal k is " << optimal_k << std::endl;
|
||||
|
||||
// Runtime (b)
|
||||
std::cout << "############ RUNTIME (ultraSortParam) ############ \n";
|
||||
for (int size = 10000; size <= 100000; size *= 10) {
|
||||
std::cout << " " << size << " Elemente:" << std::endl;
|
||||
|
||||
array = hf::zufalls_array(size);
|
||||
|
||||
time = clock();
|
||||
ultraSortParam(array, optimal_k);
|
||||
time = clock() - time;
|
||||
|
||||
std::cout << " Zufällig: " << (time/CLOCKS_PER_SEC) << " Sekunden" << std::endl;
|
||||
|
||||
array = hf::sortiertes_array(size, true);
|
||||
|
||||
time = clock();
|
||||
ultraSortParam(array, optimal_k);
|
||||
time = clock() - time;
|
||||
|
||||
std::cout << " Aufsteigend: " << (time/CLOCKS_PER_SEC) << " Sekunden" << std::endl;
|
||||
|
||||
array = hf::sortiertes_array(size, false);
|
||||
|
||||
time = clock();
|
||||
ultraSortParam(array, optimal_k);
|
||||
time = clock() - time;
|
||||
|
||||
std::cout << " Absteigend: " << (time/CLOCKS_PER_SEC) << " Sekunden" << std::endl;
|
||||
|
||||
if (isSorted(array)) {
|
||||
std::cout << " Array is sorted.\n";
|
||||
} else {
|
||||
std::cout << " Array is not sorted.\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool isSorted(const std::vector<int>& vec) {
|
||||
for (size_t i = 0; i < vec.size() - 1; ++i) {
|
||||
if (vec[i] > vec[i + 1]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void insertionSort(std::vector<int>& elems){
|
||||
int key=elems[0];
|
||||
unsigned shiftindex;
|
||||
for(unsigned i = 1; i<elems.size();i++){
|
||||
key=elems[i];
|
||||
for(shiftindex=i; shiftindex>0&&elems[shiftindex-1]>=key;shiftindex--){
|
||||
elems[shiftindex] = elems[shiftindex-1];
|
||||
}
|
||||
elems[shiftindex] = key;
|
||||
}
|
||||
}
|
||||
|
||||
void merge(std::vector<int>& first_part, std::vector<int>& second_part, std::vector<int>& elems){
|
||||
unsigned i = 0;
|
||||
unsigned j = 0;
|
||||
unsigned begin = 0;
|
||||
unsigned end = elems.size();
|
||||
|
||||
while(begin + i + j < end){
|
||||
if ( j >= second_part.size() || ((i<first_part.size()) && (first_part[i]<second_part[j]))){
|
||||
elems[begin+i+j] = first_part[i];
|
||||
i++;
|
||||
}
|
||||
else{
|
||||
elems[begin+i+j] = second_part[j];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ultraSort(std::vector<int>& elems){
|
||||
if (elems.size() <= 1) {
|
||||
return;
|
||||
}
|
||||
if (elems.size() < 10) {
|
||||
insertionSort(elems);
|
||||
return;
|
||||
}
|
||||
int groesse_erster_teil = elems.size() / 3;
|
||||
std::vector<int> erster_teil(elems.begin(), elems.begin() + groesse_erster_teil);
|
||||
std::vector<int> zweiter_teil(elems.begin() + groesse_erster_teil, elems.end());
|
||||
insertionSort(erster_teil);
|
||||
ultraSort(zweiter_teil);
|
||||
merge(erster_teil, zweiter_teil, elems);
|
||||
}
|
||||
|
||||
void ultraSortParam(std::vector<int>& elems, double k){
|
||||
if (elems.size() <= 1) {
|
||||
return;
|
||||
}
|
||||
if (elems.size() < 10) {
|
||||
insertionSort(elems);
|
||||
return;
|
||||
}
|
||||
int groesse_erster_teil = static_cast<int>(k * elems.size());
|
||||
std::vector<int> erster_teil(elems.begin(), elems.begin() + groesse_erster_teil);
|
||||
std::vector<int> zweiter_teil(elems.begin() + groesse_erster_teil, elems.end());
|
||||
insertionSort(erster_teil);
|
||||
ultraSortParam(zweiter_teil, k);
|
||||
merge(erster_teil, zweiter_teil, elems);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
/*
|
||||
- Voraussetzungen: str ist ein String
|
||||
- Ergebnis: str ist ein String, der nur aus Großbuchstaben besteht
|
||||
- Seiteneffekte: keine
|
||||
|
||||
Der Rückgabetyp ist string, weil wir einen neuen String zurückgeben wollen, der nur aus Großbuchstaben besteht.
|
||||
Der Parameter ist string, weil wir einen String übergeben wollen, bei dem wir die Buchstaben in Großbuchstaben umwandeln wollen.
|
||||
|
||||
*/
|
||||
std::string upper(std::string str);
|
||||
|
||||
int main() {
|
||||
|
||||
std::cout << "Bitte gebe einen String ein der groß geschrieben werden soll: ";
|
||||
std::string s;
|
||||
std::getline(std::cin, s);
|
||||
std::cout << "Hier ist dein neuer String: " << upper(s) << std::endl;
|
||||
|
||||
}
|
||||
|
||||
std::string upper(std::string str) {
|
||||
for (unsigned i = 0; i < str.length(); i++) {
|
||||
if (str[i] >= 'a' && str[i] <= 'z') {
|
||||
str[i] = str[i] - 32;
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/* Informatik B - Sommersemester 2023
|
||||
Vorlesung am 28.04.2023
|
||||
Katharina Klost
|
||||
|
||||
Beispiele zu vector
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
int main(){
|
||||
|
||||
std::vector<int> zahlen = {10,4,20,24,7,34,1,55,34,17,4};
|
||||
|
||||
//vector mit 10 Boolean einträgen, die alle 0 bzw false sind
|
||||
std::vector<bool> wahrheitswerte(10);
|
||||
|
||||
//vector mit 5 Einträgen, alle sind "Mo"
|
||||
std::vector<std::string> montage(5,"Mo");
|
||||
|
||||
std::cout << zahlen[3] << std::endl;
|
||||
|
||||
zahlen[3] = 100;
|
||||
|
||||
std::cout << zahlen[3] << std::endl;
|
||||
std::cout << zahlen.size() << std::endl;
|
||||
zahlen.push_back(1234);
|
||||
std::cout << zahlen.size() << std::endl;
|
||||
|
||||
|
||||
//ACHTUNG! Kein Fehler, wenn wir auf Daten außerhalb des vector zugreifen
|
||||
std::cout << zahlen[zahlen.size()] << std::endl;
|
||||
|
||||
|
||||
//Wird auf einen Index größer oder gleich size() des vector
|
||||
// zugegriffen gibt es undefiniertes Verhalten.
|
||||
// Es kann ein Wert zurückgegeben werde, oder ein Speicherzugriffehler
|
||||
// ausgegeben werden.
|
||||
// Wird ein Wert außerhalb der Grenzen zugewiesen, wird die Größe
|
||||
// des vector nicht angepasst
|
||||
std::cout << zahlen[100000] << std::endl;
|
||||
std::cout << zahlen.size() << std::endl;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/* Informatik B - Sommersemester 2023
|
||||
Vorlesung am 28.04.2023
|
||||
Katharina Klost
|
||||
|
||||
Beispiele zu vector und schleifen
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
int main(){
|
||||
std::vector<int> zahlen = {10,4,20,24,7,34,1,55,34,17,4};
|
||||
int sum = 0;
|
||||
|
||||
//Schleife läuft durch alle Indizes des vector und summiert die Einträge auf
|
||||
for (unsigned int i = 0; i<zahlen.size(); i++){
|
||||
sum += zahlen[i];
|
||||
}
|
||||
|
||||
std::cout << "Summe des vector: " << sum << std::endl;
|
||||
|
||||
//Verschachtelte Schleife geht durch alle Paare i,j mit i<j und i,j < zahlen.size()
|
||||
std::cout << "Alle paare von Werten: " << std::endl;
|
||||
for(unsigned i = 0; i< zahlen.size(); i++){
|
||||
for(unsigned j = i+1; j<zahlen.size(); j++){
|
||||
std::cout << "(" << zahlen[i] << ", " << zahlen[j] <<")" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
/*
|
||||
KLassenhierarchie
|
||||
|
||||
1. tier
|
||||
Attribute: gewicht, groesse
|
||||
Methoden: fortbewegen(), atmen(), essen()
|
||||
1.1. saeugetier
|
||||
1.1.1. hund
|
||||
Attribute: gattung
|
||||
Methoden: anbellen(tier t), fortpflanzen(hund h)
|
||||
1.1.1.1. pudel
|
||||
1.2. insekt
|
||||
1.2.1. biene
|
||||
*/
|
||||
|
||||
/*
|
||||
Klasse Tier: Basis-Klasse in der Klassenstruktur.
|
||||
Kann genutzt werden, um allgemeine Eigenschaften und Verhaltensweisen von Tieren abzubilden.
|
||||
Wir haben die Methoden essen(), atmen(), und fortbewegen() als virtual in der Basisklasse Tier definiert, was bedeutet, dass sie in den abgeleiteten Klassen überschrieben werden koennen, wenn dies gewünscht wird.
|
||||
*/
|
||||
class Tier
|
||||
{
|
||||
public:
|
||||
int gewicht;
|
||||
int groesse;
|
||||
|
||||
// Konstruktor: Kann aufgerufen werden, um ein neues Tierobjekt mit definiertem Gewicht und Groesse zu erstellen.
|
||||
// Gibt ein neues Tierobjekt zurück.
|
||||
// Fügt dem Programmzustand ein neues Tierobjekt hinzu.
|
||||
Tier(int gewicht, int groesse) : gewicht(gewicht), groesse(groesse) {}
|
||||
|
||||
// Destruktor: Wird aufgerufen, wenn ein Tierobjekt geloescht wird.
|
||||
// Gibt nichts zurück.
|
||||
// Entfernt das Tierobjekt aus dem Zustand des Programms.
|
||||
~Tier() {}
|
||||
|
||||
// Kann aufgerufen werden, um das Verhalten eines Tiers zu simulieren, sich fortzubewegen.
|
||||
// Gibt Text zurück und hat keine Effekte.
|
||||
virtual void fortbewegen()
|
||||
{
|
||||
std::cout << "Tier bewegt sich fort." << std::endl;
|
||||
}
|
||||
|
||||
// Kann aufgerufen werden, um das Verhalten eines Tiers zu simulieren, zu atmen.
|
||||
// Gibt Text zurück und hat keine Effekte.
|
||||
virtual void atmen()
|
||||
{
|
||||
std::cout << "Tier atmet." << std::endl;
|
||||
}
|
||||
|
||||
// Kann aufgerufen werden, um das Verhalten eines Tiers zu simulieren, zu essen.
|
||||
// Gibt Text zurück und hat keine Effekte.
|
||||
virtual void essen()
|
||||
{
|
||||
std::cout << "Tier isst." << std::endl;
|
||||
}
|
||||
|
||||
// Kann aufgerufen werden, um das Gewicht des Tiers zu ermitteln.
|
||||
// Gibt das Gewicht des Tiers als Integer zurück.
|
||||
// Ändert den Zustand des Programms nicht.
|
||||
int getGewicht()
|
||||
{
|
||||
return gewicht;
|
||||
}
|
||||
|
||||
// Kann aufgerufen werden, um die Groesse des Tiers zu ermitteln.
|
||||
// Gibt die Groesse des Tiers als Integer zurück.
|
||||
// Ändert den Zustand des Programms nicht.
|
||||
int getGroesse()
|
||||
{
|
||||
return groesse;
|
||||
}
|
||||
};
|
||||
|
||||
// Klasse Saeugetier (Säugetier): Erbt von der Klasse Tier.
|
||||
// Kann genutzt werden, um ein spezifisches Tier zu erstellen, das ein Säugetier ist.
|
||||
class Saeugetier : public Tier
|
||||
{
|
||||
public:
|
||||
// Konstruktor: Kann aufgerufen werden, um ein neues Saeugetier-Objekt mit definiertem Gewicht und Groesse zu erstellen.
|
||||
// Gibt ein neues Saeugetier-Objekt zurück.
|
||||
// Fügt dem Programmzustand ein neues Saeugetier-Objekt hinzu.
|
||||
Saeugetier(int gewicht, int groesse) : Tier(gewicht, groesse) {}
|
||||
};
|
||||
|
||||
// Klasse Hund: Erbt von der Klasse Saeugetier.
|
||||
// Kann genutzt werden, um ein spezifisches Tier zu erstellen, das ein Hund ist.
|
||||
class Hund : public Saeugetier
|
||||
{
|
||||
|
||||
public:
|
||||
std::string gattung;
|
||||
|
||||
// Konstruktor: Kann aufgerufen werden, um ein neues Hund-Objekt mit definiertem Gewicht, Groesse und Gattung zu erstellen.
|
||||
// Gibt ein neues Hund-Objekt zurück.
|
||||
// Fügt dem Programmzustand ein neues Hund-Objekt hinzu.
|
||||
Hund(int gewicht, int groesse, std::string gattung) : Saeugetier(gewicht, groesse), gattung(gattung) {}
|
||||
|
||||
// Destruktor: Wird aufgerufen, wenn ein Hund-Objekt geloescht wird.
|
||||
// Gibt nichts zurück.
|
||||
// Entfernt das Hund-Objekt aus dem Zustand des Programms.
|
||||
~Hund() {}
|
||||
|
||||
// Kann aufgerufen werden, um das Verhalten eines Hundes zu simulieren, ein anderes Tier anzubellen.
|
||||
// Gibt Text zurück und hat keine Effekte.
|
||||
void anbellen(Tier t)
|
||||
{
|
||||
std::cout << "Hund bellt anderen Hund an" << std::endl;
|
||||
}
|
||||
|
||||
// Kann aufgerufen werden, um das Verhalten eines Hundes zu simulieren, sich fortzupflanzen.
|
||||
// Gibt Text zurück und hat keine Effekte.
|
||||
void fortpflanzen(Hund h)
|
||||
{
|
||||
std::cout << "Hund pflanzt sich mit anderem Hund fort" << std::endl;
|
||||
}
|
||||
|
||||
// Kann aufgerufen werden, um die Gattung des Hundes zu ermitteln.
|
||||
// Gibt die Gattung des Hundes als String zurück.
|
||||
// Ändert den Zustand des Programms nicht.
|
||||
std::string getGattung()
|
||||
{
|
||||
return gattung;
|
||||
}
|
||||
};
|
||||
|
||||
// Klasse Pudel: Erbt von der Klasse Hund.
|
||||
// Kann genutzt werden, um ein spezifisches Tier zu erstellen, das ein Pudel ist.
|
||||
class Pudel : public Hund
|
||||
{
|
||||
public:
|
||||
// Konstruktor: Kann aufgerufen werden, um ein neues Pudel-Objekt mit definiertem Gewicht, Groesse und Gattung zu erstellen.
|
||||
// Gibt ein neues Pudel-Objekt zurück.
|
||||
// Fügt dem Programmzustand ein neues Pudel-Objekt hinzu.
|
||||
Pudel(int gewicht, int groesse, std::string gattung) : Hund(gewicht, groesse, gattung) {}
|
||||
|
||||
// Destruktor: Wird aufgerufen, wenn ein Pudel-Objekt geloescht wird.
|
||||
// Gibt nichts zurück.
|
||||
// Entfernt das Pudel-Objekt aus dem Zustand des Programms.
|
||||
~Pudel() {}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Pudel Bello(10, 45, "Pudel");
|
||||
Pudel Strolch(20, 60, "Pudel");
|
||||
|
||||
int gewichtBello = Bello.getGewicht();
|
||||
int groesseBello = Bello.getGroesse();
|
||||
std::string gattungBello = Bello.getGattung();
|
||||
|
||||
std::cout << "Ein Hund der gattung " << gattungBello << ", mit der groesse " << groesseBello << " und mit dem Gewicht " << gewichtBello << " wurde erstellt" << std::endl;
|
||||
|
||||
Bello.essen();
|
||||
Bello.atmen();
|
||||
Bello.fortbewegen();
|
||||
Bello.anbellen(Strolch);
|
||||
Bello.fortpflanzen(Strolch);
|
||||
}
|
||||
Reference in New Issue
Block a user