diff options
feat(Week01): Add solutions
12 files changed, 371 insertions, 0 deletions
| -rw-r--r-- | Week01/Exercise01/main.cpp | 29 | ||||
| -rw-r--r-- | Week01/Exercise01/matrix.cpp | 28 | ||||
| -rw-r--r-- | Week01/Exercise01/matrix.h | 11 | ||||
| -rw-r--r-- | Week01/Exercise02/arrmath.cpp | 57 | ||||
| -rw-r--r-- | Week01/Exercise02/arrmath.h | 15 | ||||
| -rw-r--r-- | Week01/Exercise02/main.cpp | 26 | ||||
| -rw-r--r-- | Week01/Exercise03/ioHelpers.cpp | 57 | ||||
| -rw-r--r-- | Week01/Exercise03/ioHelpers.h | 17 | ||||
| -rw-r--r-- | Week01/Exercise03/main.cpp | 40 | ||||
| -rw-r--r-- | Week01/Exercise03/stringHelpers.cpp | 74 | ||||
| -rw-r--r-- | Week01/Exercise03/stringHelpers.h | 14 | ||||
| -rw-r--r-- | Week01/README.md | 3 |
diff --git a/Week01/Exercise01/main.cpp b/Week01/Exercise01/main.cpp new file mode 100644 index 0000000..7958615 --- /dev/null +++ b/Week01/Exercise01/main.cpp @@ -0,0 +1,29 @@ +#include <iostream> +#include "matrix.h" + +int main() { + unsigned rowsA, colsA; + std::cin >> rowsA >> colsA; + + int** matA = newMatrix(rowsA, colsA); + + for (unsigned row = 0; row < rowsA; ++row) + for (unsigned col = 0; col < colsA; ++col) + std::cin >> matA[row][col]; + + unsigned rowsB, colsB; + std::cin >> rowsB >> colsB; + + int** matB = newMatrix(rowsB, colsB); + + for (unsigned row = 0; row < rowsB; ++row) + for (unsigned col = 0; col < colsB; ++col) + std::cin >> matB[row][col]; + + std::cout << (sumMatrix((const int**)matA, rowsA, colsA) - sumMatrix((const int**)matB, rowsB, colsB)) << std::endl; + + deleteMatrix(matA, rowsA); + deleteMatrix(matB, rowsB); + + return 0; +} diff --git a/Week01/Exercise01/matrix.cpp b/Week01/Exercise01/matrix.cpp new file mode 100644 index 0000000..c8bdff2 --- /dev/null +++ b/Week01/Exercise01/matrix.cpp @@ -0,0 +1,28 @@ +#include "matrix.h" + +int** newMatrix(unsigned rows, unsigned cols) { + int** mat = new int*[rows]; + + for (unsigned i = 0; i < rows; ++i) + mat[i] = new int[cols]; + + return mat; +} + +void deleteMatrix(int**& matrix, unsigned rows) { + for (unsigned i = 0; i < rows; ++i) + delete[] matrix[i]; + delete[] matrix; + + matrix = nullptr; +} + +int sumMatrix(const int** matrix, unsigned rows, unsigned cols) { + int sum = 0; + + for (unsigned row = 0; row < rows; ++row) + for (unsigned col = 0; col < cols; ++col) + sum += matrix[row][col]; + + return sum; +} diff --git a/Week01/Exercise01/matrix.h b/Week01/Exercise01/matrix.h new file mode 100644 index 0000000..334fab0 --- /dev/null +++ b/Week01/Exercise01/matrix.h @@ -0,0 +1,11 @@ +#ifndef _MATRIX +#define _MATRIX + +// Създава нова динамично-заделена матрица +int** newMatrix(unsigned rows, unsigned cols); +// Изтрива динамично-заделена матрица +void deleteMatrix(int**& matrix, unsigned rows); // Запишете nullptr в matrix! +// Връща сумата на всички елементи в матрицата +int sumMatrix(const int** matrix, unsigned rows, unsigned cols); + +#endif diff --git a/Week01/Exercise02/arrmath.cpp b/Week01/Exercise02/arrmath.cpp new file mode 100644 index 0000000..d518134 --- /dev/null +++ b/Week01/Exercise02/arrmath.cpp @@ -0,0 +1,57 @@ +#include "arrmath.h" + +int sum(const int* elements, unsigned length) { + if (elements == nullptr || length == 0) + return 0; + + int sum = 0; + + for (unsigned i = 0; i < length; ++i) + sum += elements[i]; + + return sum; +} + +double average(const int* elements, unsigned length) { + if (elements == nullptr || length == 0) + return 0.0; + + return (double)sum(elements, length) / length; +} + +int largest(const int* elements, unsigned length) { + if (elements == nullptr || length == 0) + return 0; + + int largest = elements[0]; + for (unsigned i = 1; i < length; ++i) + if (elements[i] > largest) + largest = elements[i]; + + return largest; +} + +int smallest(const int* elements, unsigned length) { + if (elements == nullptr || length == 0) + return 0; + + int smallest = elements[0]; + for (unsigned i = 1; i < length; ++i) + if (elements[i] < smallest) + smallest = elements[i]; + + return smallest; +} + +unsigned findIndex(const int* elements, unsigned length, int elementToSearch) { + if (elements == nullptr || length == 0) + return length; + + for (unsigned i = 0; i < length; ++i) + if (elements[i] == elementToSearch) + return i; + + // Коректно е да връщаме length вместо 0, защото + // 0 може да е валиден индекс в масива с елементи + return length; +} diff --git a/Week01/Exercise02/arrmath.h b/Week01/Exercise02/arrmath.h new file mode 100644 index 0000000..4f1a550 --- /dev/null +++ b/Week01/Exercise02/arrmath.h @@ -0,0 +1,15 @@ +#ifndef ARRMATH +#define ARRMATH + +// Сума на стойностите в elements +int sum(const int* elements, unsigned length); +// Средно аритметично на стойностите в elements +double average(const int* elements, unsigned length); +// Най-голямата стойност в elements +int largest(const int* elements, unsigned length); +// Най-малката стойност в elements +int smallest(const int* elements, unsigned length); +// Връща индекса на първото срещане на elementToSearch +unsigned findIndex(const int* elements, unsigned length, int elementToSearch); + +#endif diff --git a/Week01/Exercise02/main.cpp b/Week01/Exercise02/main.cpp new file mode 100644 index 0000000..9e3c593 --- /dev/null +++ b/Week01/Exercise02/main.cpp @@ -0,0 +1,26 @@ +#include <iostream> +#include "arrmath.h" + +int main() { + unsigned N; + std::cin >> N; + + int* arr = new int[N]; + for (unsigned i = 0; i < N; ++i) + std::cin >> arr[i]; + + int startIndex = findIndex(arr, N, smallest(arr, N)); + int endIndex = findIndex(arr, N, largest(arr, N)); + + if (startIndex > endIndex) { + int temp = startIndex; + startIndex = endIndex; + endIndex = temp; + } + + std::cout << average(arr + startIndex, endIndex - startIndex + 1) << std::endl; + + delete[] arr; + + return 0; +} diff --git a/Week01/Exercise03/ioHelpers.cpp b/Week01/Exercise03/ioHelpers.cpp new file mode 100644 index 0000000..caf63fe --- /dev/null +++ b/Week01/Exercise03/ioHelpers.cpp @@ -0,0 +1,57 @@ +#include <iostream> +#include "ioHelpers.h" +#include "stringHelpers.h" + +int readInteger(const char* prompt, int min, int max) { + std::cout << prompt; + + int value; + std::cin >> value; + + while (value < min || max < value) { + std::cout << "Value must in range [" << min << ", " << max << "]! Try again... " << std::endl; + std::cin >> value; + } + + return value; +} + +double readDouble(const char* prompt, double min, double max) { + std::cout << prompt; + + double value; + std::cin >> value; + + while (value < min || max < value) { + std::cout << "Value must in range [" << min << ", " << max << "]! Try again... " << std::endl; + std::cin >> value; + } + + return value; +} + +char* readString(const char* prompt) { + std::cout << prompt; + + const unsigned BUFFER_SIZE = 1024; + char buffer[BUFFER_SIZE]; + + // Когато правим "std::cin >> x", std::cin чете само нужния брой знаци за x, + // докато std::cin.getline чете от последната позиция нататък. + // Тоест, ако направим например "std::cin >> integerValue" и след това + // "std::cin.getline(...)" и входа ни е "5 ABC", тогава първото std::cin + // ще прочете само 5-цата и getline ще запише " ABC". + // Когато обаче имаме нов ред, тоест еквивалентно на "5\nABC", тогава + // getline ще почне да чете от "\nABC", ще види това "\n" и ще запише + // празния низ "". + // std::cin.peek() връща текущата буква, без да премества напред четенето, + // std::cin.ignore() игнорира една буква (т.е. четенето продължава след нея). + // Общо взето, това долу игнорира знак за нов ред, ако сме срещнали такъв. + // Това оправя ситуацията, когато получаваме "First name: Last name: ". + if (std::cin.peek() == '\n') + std::cin.ignore(); + + std::cin.getline(buffer, BUFFER_SIZE); + + return newString(buffer); +} diff --git a/Week01/Exercise03/ioHelpers.h b/Week01/Exercise03/ioHelpers.h new file mode 100644 index 0000000..bf365dd --- /dev/null +++ b/Week01/Exercise03/ioHelpers.h @@ -0,0 +1,17 @@ +#ifndef IOHELPERS +#define IOHELPERS + +// Прочита от потребителския вход цяло число между min и max включително, +// като предоставя prompt преди въведената стойност +// При невалидна стойност, пита пак за вход +int readInteger(const char* prompt, int min, int max); +// Прочита от потребителския вход число с плаваща запетая между min и max включително, +// като предоставя prompt преди въведената стойност +// При невалидна стойност, пита пак за вход +double readDouble(const char* prompt, double min, double max); +// Прочита от потребителския вход един ред текст, +// като предоставя prompt преди въведената стойност +// При невалидна стойност, пита пак за вход +char* readString(const char* prompt); + +#endif diff --git a/Week01/Exercise03/main.cpp b/Week01/Exercise03/main.cpp new file mode 100644 index 0000000..beea1f5 --- /dev/null +++ b/Week01/Exercise03/main.cpp @@ -0,0 +1,40 @@ +#include <iostream> +#include "ioHelpers.h" +#include "stringHelpers.h" + +int main() { + // Нямаме ограничение на броя студенти, затова просто ще сложим максимума + // да е най-голямата стойност за 32-битов signed integer: 2^31 - 1 + // По-коректно е да се ползват специални константи, които пазят максималната + // стойност на отделните типове данни, защото на стар компютър, int може да + // не е 32 бита. + unsigned numStudents = readInteger("Number of students: ", 0, 2147483647); + + double* grades = new double[numStudents]; + char** names = new char*[numStudents]; + + for (unsigned i = 0; i < numStudents; ++i) { + char* firstName = readString("First name: "); + char* lastName = readString("Last name: "); + + names[i] = concatStrings(firstName, lastName, " "); + + deleteString(firstName); + deleteString(lastName); + + double grade = readDouble("Grade: ", 2.0, 6.0); + + grades[i] = grade; + } + + for (unsigned i = 0; i < numStudents; ++i) { + std::cout << names[i] << " has grade " << grades[i] << std::endl; + } + + delete[] grades; + for (unsigned i = 0; i < numStudents; ++i) + deleteString(names[i]); + delete[] names; + + return 0; +} diff --git a/Week01/Exercise03/stringHelpers.cpp b/Week01/Exercise03/stringHelpers.cpp new file mode 100644 index 0000000..ee9e691 --- /dev/null +++ b/Week01/Exercise03/stringHelpers.cpp @@ -0,0 +1,74 @@ +#include "stringHelpers.h" + +char* newString(unsigned length) { + return new char[length + 1]; +} + +// Тази функция е локална: не можем да я използваме в друг файл! +unsigned stringLength(const char* string) { + if (string == nullptr) + return 0; + + unsigned length = 0; + + while (*string != '\0') { + ++length; + ++string; + } + + return length; +} + +char* newString(const char* string) { + if (string == nullptr) + return nullptr; + + unsigned length = stringLength(string); + + char* str = newString(length); + + // Правим <= length, за да пренесем и терминиращата нула + for (unsigned i = 0; i <= length; ++i) { + str[i] = string[i]; + } + + return str; +} + +char* concatStrings(const char* first, const char* second, const char* separator) { + unsigned length = stringLength(first) + stringLength(separator) + stringLength(second); + + char* str = newString(length); + unsigned i = 0; + + if (first != nullptr) { + while (*first != '\0' && i < length) { + str[i] = *first; + ++first; + ++i; + } + } + + if (separator != nullptr) { + while (*separator != '\0' && i < length) { + str[i] = *separator; + ++separator; + ++i; + } + } + + if (second != nullptr) { + while (*second != '\0' && i < length) { + str[i] = *second; + ++second; + ++i; + } + } + + return str; +} + +void deleteString(char*& string) { + delete[] string; + string = nullptr; +} diff --git a/Week01/Exercise03/stringHelpers.h b/Week01/Exercise03/stringHelpers.h new file mode 100644 index 0000000..7f86130 --- /dev/null +++ b/Week01/Exercise03/stringHelpers.h @@ -0,0 +1,14 @@ +#ifndef STRINGHELPERS +#define STRINGHELPERS + +// Създава динамично-заделен низ по подадената дължина +char* newString(unsigned length); +// Създава динамично-заделен низ, копие на подадения низ +char* newString(const char* string); +// Слепява first и second, като поставя separator между тях (ако е валиден) и +// връща резултатния (динамичо-заделен) низ +char* concatStrings(const char* first, const char* second, const char* separator); +// Освобождава паметта на динамичо-заделен низ +void deleteString(char*& string); // Запишете nullptr в string! + +#endif diff --git a/Week01/README.md b/Week01/README.md new file mode 100644 index 0000000..69458d7 --- /dev/null +++ b/Week01/README.md @@ -0,0 +1,3 @@ +# Задачи + +<https://syndamia.com/teaching/oop-2025/week01/> |
