From 5e3792e3893940a545b660139d9b5c2e2e2af706 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 26 Dec 2025 16:55:14 +0500 Subject: [PATCH 01/65] Update phasor.cpp --- 04_week/tasks/phasor/phasor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/04_week/tasks/phasor/phasor.cpp b/04_week/tasks/phasor/phasor.cpp index 3ec1b9ad..fa99de69 100644 --- a/04_week/tasks/phasor/phasor.cpp +++ b/04_week/tasks/phasor/phasor.cpp @@ -6,5 +6,5 @@ struct AlgTag {}; class Phasor { - + }; From 4f1cfc11eee354c931f451b32bf31e2058b70876 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 26 Dec 2025 20:09:15 +0500 Subject: [PATCH 02/65] Update stack.cpp Stack --- 04_week/tasks/stack/stack.cpp | 66 +++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/04_week/tasks/stack/stack.cpp b/04_week/tasks/stack/stack.cpp index 222e4ffc..04841d83 100644 --- a/04_week/tasks/stack/stack.cpp +++ b/04_week/tasks/stack/stack.cpp @@ -2,5 +2,71 @@ class Stack { + public: + // методы: + + void Push(int newData); // Добавление нэлемента в стек + + bool Pop(void); // удаление элемента с верхушки стека + + int& Top(); // Доступ к элементу на вершине стека + + const int& Top() const; // Доступ к элементу на вершине стека + + bool Empty() const; // Проверка отсутсвия элементов на вершине + + size_t Size() const; // Размер стека + + void Clear(); // Очистка стека + + void Swap(Stack& other); // меняем местами элементы + + // определение для == + bool operator==(const Stack& x) const {return data == x.data;} + + // определение для != + bool operator!=(const Stack& x) const {return !(data == x.data);} + + private: + std::vector data; // данные }; + + + +// в Методах для Stack используем методы для vector + +void Stack::Push(int newData){ + data.push_back(newData); +} + +bool Stack::Pop(void){ + if(data.empty()) return false; + data.pop_back(); + return true; +} + +int& Stack::Top(){ + return data.back(); +} + +const int& Stack::Top() const{ + return data.back(); +} + +bool Stack::Empty() const{ + return data.empty(); +} + +size_t Stack::Size() const{ + return data.size(); +} + +void Stack::Clear() { + data.clear(); +} + +void Stack::Swap(Stack& other){ + data.swap(other.data); +} + From be4a8cb884780ec8120566974756a433263173b7 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 26 Dec 2025 20:12:25 +0500 Subject: [PATCH 03/65] Update CMakeLists.txt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Временно отключаю контроль задачь недели 3 --- 03_week/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/03_week/CMakeLists.txt b/03_week/CMakeLists.txt index e5df5bac..fb663b00 100644 --- a/03_week/CMakeLists.txt +++ b/03_week/CMakeLists.txt @@ -7,11 +7,11 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) # Гарантирует использов set(EXAMPLES_DIR examples) # Определим переменную с именем директории set(TASKS_DIR tasks) -add_subdirectory(tasks) + #add_subdirectory(tasks) # Создать исполняемый файл для каждого примера if (BUILD_EXAMPLES_03_WEEK) add_example(struct_examples ${EXAMPLES_DIR}/struct_examples.cpp) add_example(union_examples ${EXAMPLES_DIR}/union_examples.cpp) add_example(vector_examples ${EXAMPLES_DIR}/vector_examples.cpp) -endif() \ No newline at end of file +endif() From f42a9980b76908b42aabf2d2cd553fd288b91e61 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 26 Dec 2025 20:13:08 +0500 Subject: [PATCH 04/65] Update CMakeLists.txt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Временно отключаю контроль задачь недели 2 иначе в проверке куча строк. --- 02_week/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/02_week/CMakeLists.txt b/02_week/CMakeLists.txt index 625e6fbe..856d2248 100644 --- a/02_week/CMakeLists.txt +++ b/02_week/CMakeLists.txt @@ -7,7 +7,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) # Гарантирует использов set(EXAMPLES_DIR examples) # Определим переменную с именем директории set(TASKS_DIR tasks) -add_subdirectory(tasks) +#add_subdirectory(tasks) # Создать исполняемый файл для каждого примера if (BUILD_EXAMPLES_02_WEEK) @@ -17,4 +17,4 @@ if (BUILD_EXAMPLES_02_WEEK) add_example(ptr_access ${EXAMPLES_DIR}/ptr_access.cpp) add_example(ptr_arithmetic ${EXAMPLES_DIR}/ptr_arithmetic.cpp) add_example(reinterpret ${EXAMPLES_DIR}/reinterpret.cpp) -endif() \ No newline at end of file +endif() From d7911f1d19a4f1c91630762e7704c267e06a180c Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 26 Dec 2025 20:13:46 +0500 Subject: [PATCH 05/65] Update CMakeLists.txt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Временно отключаю контроль задачь недели 1 иначе в проверке куча строк. --- 01_week/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/01_week/CMakeLists.txt b/01_week/CMakeLists.txt index 5ecaacbc..166189d5 100644 --- a/01_week/CMakeLists.txt +++ b/01_week/CMakeLists.txt @@ -7,7 +7,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) # Гарантирует использов set(EXAMPLES_DIR examples) # Определим переменную с именем директории set(TASKS_DIR tasks) -add_subdirectory(tasks) +#add_subdirectory(tasks) # Создать исполняемый файл для каждого примера if (BUILD_EXAMPLES_01_WEEK) @@ -32,4 +32,4 @@ if (BUILD_EXAMPLES_01_WEEK) add_example(functions_recursive ${EXAMPLES_DIR}/functions_recursive.cpp) add_example(io_streams ${EXAMPLES_DIR}/io_streams.cpp) add_example(main_with_args ${EXAMPLES_DIR}/main_with_args.cpp) -endif() \ No newline at end of file +endif() From 28f780ab60cb75ec69cce81f36bd79384a33fe4b Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 26 Dec 2025 23:01:20 +0500 Subject: [PATCH 06/65] Update ring_buffer.cpp --- 04_week/tasks/ring_buffer/ring_buffer.cpp | 145 ++++++++++++++++++++++ 1 file changed, 145 insertions(+) diff --git a/04_week/tasks/ring_buffer/ring_buffer.cpp b/04_week/tasks/ring_buffer/ring_buffer.cpp index e2b57ba2..dc9eb16b 100644 --- a/04_week/tasks/ring_buffer/ring_buffer.cpp +++ b/04_week/tasks/ring_buffer/ring_buffer.cpp @@ -1,6 +1,151 @@ #include + class RingBuffer { +public: + + // ---- Конструкторы ----- + explicit RingBuffer(size_t capacity); // Конструктор от емкости + RingBuffer(size_t capacity, int initialValue); // Конструткор от емкасти и начального значения + RingBuffer(std::initializer_list init); // конструктор по размеру контейнера + + // ---- Методы ----- + void Push(int value); + bool TryPush(int value); + + bool Pop(); + bool TryPop(int& value); + + int& Front(); + const int& Front() const; + int& Back(); + const int& Back() const; + + bool Empty() const {return countElem == 0;} + bool Full() const {return countElem == buf.capacity();} + size_t Size() const{return countElem;} + size_t Capacity() const{return buf.capacity();} + + void Clear() {prevElem = nextElem = countElem = 0;} + void Resize(size_t newCapacity); + + std::vector Vector() const; + + bool operator==(const RingBuffer& other) const; + bool operator!=(const RingBuffer& other) const; + int& operator[](size_t index); + const int& operator[](size_t index) const; + +private: + std::vector buf; + size_t prevElem = 0; + size_t nextElem = 0; + size_t countElem = 0; // счетчик текущего элемента + + + size_t NextIndex(size_t i) const { + if((i + 1) >= buf.capacity()) return 0; + return i+1; + } + }; + +RingBuffer::RingBuffer(size_t capacity) { + if(capacity == 0) capacity = 1; // Емкость 0 не должна быть + buf.reserve(capacity); + buf.resize(capacity); + prevElem = 0; + nextElem = 0; + countElem = 0; +} + +RingBuffer::RingBuffer(size_t capacity, int initialValue) { + + if(capacity == 0) capacity = 1; // Емкость 0 не должна быть + buf.reserve(capacity); + buf.resize(capacity); + prevElem = 0; + nextElem = 0; + countElem = 0; + for (size_t i = 0; i < capacity; ++i) Push(initialValue); + +} + +RingBuffer::RingBuffer(std::initializer_list init) { + + size_t capacity = init.size(); + if(capacity == 0) capacity = 1; // Емкость 0 не должна быть + + buf.reserve(capacity); + buf.resize(capacity); + prevElem = 0; + nextElem = 0; + countElem = 0; + + for (int value : init) Push(value); +} + +void RingBuffer::Push(int value) { + if (Full()) { + buf[nextElem] = value; + prevElem = NextIndex(prevElem); + nextElem = NextIndex(nextElem); + } else { + buf[nextElem] = value; + nextElem = NextIndex(nextElem); + ++countElem; + } +} + +bool RingBuffer::TryPush(int value) { + if (Full()) return false; + buf[nextElem] = value; + nextElem = NextIndex(nextElem); + ++countElem; + return true; +} + +bool RingBuffer::Pop() { + if (Empty()) return false; + prevElem = NextIndex(prevElem); + --countElem; + return true; +} + +bool RingBuffer::TryPop(int& value) { + if (Empty()) return false; + value = buf[prevElem]; + Pop(); + return true; +} + +int& RingBuffer::operator[](size_t i) { + if(i >= countElem) return buf[countElem]; + return buf[((i + prevElem)%buf.capacity())]; + +} + +const int& RingBuffer::operator[](size_t i) const { + if(i >= countElem) return buf[countElem]; + return buf[((i + prevElem)%buf.capacity())]; +} + +int& RingBuffer::Front() { + if(nextElem == 0) return buf[buf.capacity() - 1]; + return buf[nextElem - 1]; +} + +const int& RingBuffer::Front() const { + if(nextElem == 0) return buf[buf.capacity() - 1]; + return buf[nextElem - 1]; +} + +int& RingBuffer::Back() { + return buf[prevElem]; +} + +const int& RingBuffer::Back() const { + return buf[prevElem]; +} From d2884cac3d14227e3e8d9b21443ae2e988e6a9f3 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 26 Dec 2025 23:05:33 +0500 Subject: [PATCH 07/65] Update ring_buffer.cpp --- 04_week/tasks/ring_buffer/ring_buffer.cpp | 43 +++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/04_week/tasks/ring_buffer/ring_buffer.cpp b/04_week/tasks/ring_buffer/ring_buffer.cpp index dc9eb16b..ae43a220 100644 --- a/04_week/tasks/ring_buffer/ring_buffer.cpp +++ b/04_week/tasks/ring_buffer/ring_buffer.cpp @@ -149,3 +149,46 @@ int& RingBuffer::Back() { const int& RingBuffer::Back() const { return buf[prevElem]; } + + + + + + +void RingBuffer::Resize(size_t newCapacity) { + newCapacity = newCapacity ? newCapacity : 1; + if (newCapacity == buf.capacity()) return; + + size_t newCount = countElem < newCapacity ? countElem : newCapacity; + std::vector newBuffer = {}; + newBuffer.reserve(newCapacity); + newBuffer.resize(newCapacity); + + for (size_t i = 0; i < newCount; ++i) { + newBuffer[i] = (*this)[countElem - newCount + i]; + } + + buf = std::move(newBuffer); + prevElem = 0; + nextElem = newCount % newCapacity; + countElem = newCount; +} + +std::vector RingBuffer::Vector() const { + std::vector result; + result.reserve(countElem); + for (size_t i = 0; i < countElem; ++i) result.push_back((*this)[i]); + return result; +} + +bool RingBuffer::operator==(const RingBuffer& other) const { + if (countElem != other.countElem || buf.capacity() != other.buf.capacity()) + return false; + for (size_t i = 0; i < countElem; ++i) + if ((*this)[i] != other[i]) return false; + return true; +} + +bool RingBuffer::operator!=(const RingBuffer& other) const { + return !(*this == other); +} From 8f7f43460a2a64c66ef5b3f45cb3c855b1d28f7e Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 26 Dec 2025 23:08:53 +0500 Subject: [PATCH 08/65] Update ring_buffer.cpp From bb9d376d1342dce9104027aacb136d5ed6bf1b56 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 10:51:01 +0500 Subject: [PATCH 09/65] Update addition.cpp --- 01_week/tasks/addition/addition.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/01_week/tasks/addition/addition.cpp b/01_week/tasks/addition/addition.cpp index 92872802..1290aa2b 100644 --- a/01_week/tasks/addition/addition.cpp +++ b/01_week/tasks/addition/addition.cpp @@ -3,5 +3,7 @@ int64_t Addition(int a, int b) { - throw std::runtime_error{"Not implemented"}; -} \ No newline at end of file +int64_t res = static_cast(a); // Присвоение и приведение типов. +res = res + static_cast(b); // Вычисление суммы и приведение типов. + return res; +} From 6ee45a65375f011a8b963ee9b4b8ae85ac7803a1 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 10:51:16 +0500 Subject: [PATCH 10/65] Update char_changer.cpp --- 01_week/tasks/char_changer/char_changer.cpp | 55 ++++++++++++++++++++- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/01_week/tasks/char_changer/char_changer.cpp b/01_week/tasks/char_changer/char_changer.cpp index 3a7344d9..a4011b6c 100644 --- a/01_week/tasks/char_changer/char_changer.cpp +++ b/01_week/tasks/char_changer/char_changer.cpp @@ -1,7 +1,58 @@ #include #include +// !!!! ВАЖНО !!!! Изначальное объявление функции изменено в части инициализации передаваемого элемента с «char delimiter = ' '» на «char delimiter». +size_t CharChanger(char array[], size_t size, char delimiter) { -size_t CharChanger(char array[], size_t size, char delimiter = ' ') { - throw std::runtime_error{"Not implemented"}; + char symbol; // Актуальный символ. + char prevSymbol; // Предыдущий символ. + char newSymbol = 0; // Новый символ. + size_t i = 0; // счетчик. + size_t j = 0; // счетчик итераций для индексации элементов обновленного массива. + char numMatch = 0; + prevSymbol = ~array[i]; + + + while(i != size) // Проверка. + { + symbol = array[i]; // Присваиваем значение элемента массива для анализа. + + if(('0' <= symbol) && (symbol <= '9')) newSymbol = '*'; // Если символ - цифра меняем ее на ‘*’. + else if(('a' <= symbol) && (symbol <= 'z')) newSymbol = symbol - ('a' - 'A'); // Если символ – сточная буква, меняем ее на заглавную. + else if(('A' <= symbol) && (symbol <= 'Z')) newSymbol = symbol; // Если символ – заглавная буква – ничего не делаем. + else if(symbol == ' ') newSymbol = delimiter; // Пробел меняем на спец символ. + else newSymbol = '_'; // Все остальные символы заменяем на ‘_’. + + if(symbol != prevSymbol) // Проверка совпадения текущего символа с предыдущим. + { + prevSymbol = symbol; // Запоминаем символ. + + if(numMatch != 0) // Количество совпадений равно 0? + { + if(array[i-1] != ' ') // Проверяем, прядущий проверяемый символ – пробел. Если да то не нужно печатать количество со впавших символов. + { + if(numMatch >= 9) array[j] = '0'; // Если количество совпадении больше 10 (9 т.к. 10-1). Печатаем 0. + else array[j] = '0' + numMatch + 1; // Иначе печатаем количество одинаковых символов подряд. + j++; + } + } + numMatch = 0; // Обнуляем количество совпадений. + array[j] = newSymbol; // Записываем изменений элемент в массив символов. + j++; // Увеличение счетчика итераций для индексации элементов обновленного массива. + + } + else numMatch++; //Символы совпали, увеличиваем счетчик итераций. + + i++; // Счетчик для анализируемых элементов массива. + + if(symbol == '\0') { // Проверка символа окончания строки. + j = j-1; // уменьшаем счетчик для записи символа окончания строки в обновлённый массив. + array[j] = '\0'; // записываем символ окончания строки + return j; // возвращаемое значение - номер последнего элемента обнавленного массива. + } + } + array[j] = '\0'; + + return j; + } From 6f90138ec34e258a8d78941c39377e7e4ee789bb Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 10:51:44 +0500 Subject: [PATCH 11/65] Update rms.cpp --- 01_week/tasks/rms/rms.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/01_week/tasks/rms/rms.cpp b/01_week/tasks/rms/rms.cpp index 6882f0a9..9df36853 100644 --- a/01_week/tasks/rms/rms.cpp +++ b/01_week/tasks/rms/rms.cpp @@ -1,7 +1,16 @@ -#include +#include #include double CalculateRMS(double values[], size_t size) { - throw std::runtime_error{"Not implemented"}; -} \ No newline at end of file + double sum = 0.0; + + if(0 == size) return 0.0;// + if(&values[0] == nullptr) return 0.0; + + for(size_t i = 0; i < size; i++){ + sum += values[i]*values[i]; + } + + return std::sqrt(sum / size); +} From 216e9d9c293658a598ac82bdb3e68bd7c7abd4bb Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 10:52:06 +0500 Subject: [PATCH 12/65] Update quadratic.cpp --- 01_week/tasks/quadratic/quadratic.cpp | 60 +++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/01_week/tasks/quadratic/quadratic.cpp b/01_week/tasks/quadratic/quadratic.cpp index abf7d632..b00486ae 100644 --- a/01_week/tasks/quadratic/quadratic.cpp +++ b/01_week/tasks/quadratic/quadratic.cpp @@ -1,6 +1,60 @@ #include - +#include +#include void SolveQuadratic(int a, int b, int c) { - throw std::runtime_error{"Not implemented"}; -} \ No newline at end of file + float x1 = 0.0; // Превый корень уравнения + float x2 = 0.0; // Второй корень уравнения. + + float fA = static_cast(a); // Явное приведение типа int к float + float fB = static_cast(b); // Явное приведение типа int к float + float fC = static_cast(c); // Явное приведение типа int к float + float disc = static_cast(c); // Явное приведение типа int к float + float negativeUnit = -1; // Защита для формул при умножении на -1 + + // Если a, b, c равны нулю – решений бесконечно много. + if((a == 0) && (b == 0) && (c == 0)){ + std::cout <<"infinite solutions"; + return; + } + + // Если a, b равны нулю – решений а не равно нулю –решений нет! + if((a == 0) && (b == 0) && (c != 0)) + { + std::cout <<"no solutions"; + return; + } + + // Если x = 0 + if(((a == 0) && (c == 0)) || ((b == 0) && (c == 0))) + { + std::cout <<"0"; + return; + } + + + if(a == 0) // Своего рода ускорение вычисления при a равном нулю + { + x1 = (-fC)/fB; + std::cout << std::setprecision(6) << x1; + } + else // Решение через дискрименант + { + disc = fB * fB - 4 * fA * fC; + + if(disc < 0) + { + std::cout <<"no solutions"; + return; + } + + x1 = (negativeUnit * fB - sqrt(disc))/(2*fA); + x2 = (negativeUnit * fB + sqrt(disc))/(2*fA); + + // определяем вывод в зависимости от X1 и X2 + if (x1 == x2) std::cout << std::setprecision(6) << x1 ; + else if(x1 < x2) std::cout << std::setprecision(6) << x1 << ' ' << x2; + else std::cout << std::setprecision(6) << x2 << ' ' << x1; + + return; + } From 58c5f64dda75887b30d27257dfc3e31ef2f7cb63 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 10:52:26 +0500 Subject: [PATCH 13/65] Update print_bits.cpp --- 01_week/tasks/print_bits/print_bits.cpp | 64 ++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/01_week/tasks/print_bits/print_bits.cpp b/01_week/tasks/print_bits/print_bits.cpp index a48a43c1..242e6e9f 100644 --- a/01_week/tasks/print_bits/print_bits.cpp +++ b/01_week/tasks/print_bits/print_bits.cpp @@ -3,5 +3,67 @@ void PrintBits(long long value, size_t bytes) { - throw std::runtime_error{"Not implemented"}; + +// Защита от неверного значения размера в байтах. Размер в байтах должен быть от 1 до 8. +if(bytes == 0) return; +if(bytes > 8) return; + +char buf[90] = {'\0'}; // Объявление и инициализация массива '\0'. + +// !!!! Важно!!!!! +// при отладке были проблемы, по ну установленной причине при переводе от 5 до 8 байт некорректно выводилось значение. Связано это было с некорректным смещением 0х01. Даже если 0х01 присваивалось 64 битной переменной при смещении на значение от 32 до 64, результат был не верный, в результате анализа добегу переменная смещалось на 32 и все. +// Поэтом начались танцы с бубном и все переменные сделаны 8 битными. +unsigned long long count = 0; // Счётчик проанализированных бит +unsigned long long temp = 0; +unsigned long long sizeBit = bytes*8; // количество бит для вывода +unsigned long long countFour = 0; +unsigned long long countBuf = 0; // счетчик для элементов массива +unsigned long long countBit = 0; +char res; // +unsigned long long tempBit = 0; + + buf[0] = '0'; // присвоение значения первому элементу массива + buf[1] = 'b'; // присвоение значения второму элементу массива + + countBuf = 2; + + while( count < sizeBit) // Проверка количество проанализированных бит совпала с требуемым? + { // Нет, анализируем. + + //Усложнённая конструкция но без нее работало не корректно. + temp = (sizeBit-1 - count); + countBit = 0; + tempBit = 0x01; + while(temp > countBit) + { + countBit ++; + tempBit = tempBit << 1; + } + //Конец сложной конструкции. ее можно было свирнуть до temp = 0х01 << (sizeBit-1 - count); но так не работало при значении coun< 32. + + temp = tempBit & value; // определение 0 или 1 для конкретного бита. + + if(temp) res = '1'; + else res = '0'; + + buf[countBuf + count] = res; // Запись значения в массив. + + count++; // Увеличиваема счетчик + + if(countFour == 3) // После 4х значении надо вывести символ ''' (номер 39 в таблице ASCII). + { + if(sizeBit != count) + { + buf[countBuf + count] = 39; + countBuf++; + } + countFour = 0; + } + else countFour++; + + } + buf[countBuf+count] = '\n'; // последний элемент массива '\n' + + + std::cout << buf; // Вывод результата. } From 620c1931624beea2aeb260fdd641a2e00924e810 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 10:52:44 +0500 Subject: [PATCH 14/65] Update length_lit.cpp --- 01_week/tasks/length_lit/length_lit.cpp | 62 +++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/01_week/tasks/length_lit/length_lit.cpp b/01_week/tasks/length_lit/length_lit.cpp index e69de29b..a2956b03 100644 --- a/01_week/tasks/length_lit/length_lit.cpp +++ b/01_week/tasks/length_lit/length_lit.cpp @@ -0,0 +1,62 @@ + +// Константы для преобразования +#define IN_TO_CM 2.54 +#define FT_TO_IN 12.0 +#define M_TO_CM 100.0 + + +constexpr double operator"" _ft_to_m(long double x) { + return static_cast(x / M_TO_CM * FT_TO_IN * IN_TO_CM); // преобразование фт в метры +} + +constexpr double operator"" _ft_to_cm(long double x) { + return static_cast(x * FT_TO_IN * IN_TO_CM); // преобразование фт в см +} + +constexpr double operator"" _ft_to_in(long double x) { + return static_cast( x * FT_TO_IN); // преобразование фт в дюймы +} + + +//Дюймы +constexpr double operator"" _in_to_m(long double x) { + return static_cast(x * IN_TO_CM / M_TO_CM); +} + +constexpr double operator"" _in_to_cm(long double x) { + return static_cast(x * IN_TO_CM); // +} + +constexpr double operator"" _in_to_ft(long double x) { + return static_cast(x / FT_TO_IN); // +} + +//Метры +constexpr double operator"" _m_to_ft(long double x) { + return static_cast(x / IN_TO_CM / FT_TO_IN * M_TO_CM); // +} + +constexpr double operator"" _m_to_cm(long double x) { + return static_cast( x * M_TO_CM); // +} + +constexpr double operator"" _m_to_in(long double x) { + return static_cast(x / IN_TO_CM * M_TO_CM); // +} + + +//см +constexpr double operator"" _cm_to_ft(long double x) { + return static_cast(x / FT_TO_IN / IN_TO_CM); // +} + +constexpr double operator"" _cm_to_m(long double x) { + return static_cast(x / M_TO_CM); // +} + +constexpr double operator"" _cm_to_in(long double x) { + return static_cast(x / IN_TO_CM); // +} + + + From abc3ef0947785bfc7ed8d7142320b06bc5d2aa44 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 10:53:10 +0500 Subject: [PATCH 15/65] Update check_flags.cpp --- 01_week/tasks/check_flags/check_flags.cpp | 66 ++++++++++++++++++++++- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/01_week/tasks/check_flags/check_flags.cpp b/01_week/tasks/check_flags/check_flags.cpp index 75e7c652..8d065e0b 100644 --- a/01_week/tasks/check_flags/check_flags.cpp +++ b/01_week/tasks/check_flags/check_flags.cpp @@ -1,7 +1,6 @@ #include #include - enum class CheckFlags : uint8_t { NONE = 0, TIME = (1 << 0), @@ -14,5 +13,68 @@ enum class CheckFlags : uint8_t { }; void PrintCheckFlags(CheckFlags flags) { - throw std::runtime_error{"Not implemented"}; + + char buf[40] = {'\0'}; + uint8_t data = static_cast(flags); // приведение типа к uint8_t т.к. CheckFlags типа uint8_t + size_t i = 0; + + buf[0] = '['; + i =1; + // Проверка наличия "лишних флагов", ALL приводим к типу uint8_t + // Если есть лишние флаги, выходим. + if(data > static_cast(CheckFlags::ALL)) return; + if(data != 0) + { + if(data & static_cast(CheckFlags::TIME)){ + if(buf[i-1] != '['){ + buf[i] = ','; + i++; + } + + buf[i++] = 'T'; buf[i++] = 'I'; buf[i++] = 'M'; buf[i++] = 'E'; + } + if(data & static_cast(CheckFlags::DATE)){ + if(buf[i-1] != '['){ + buf[i] = ','; + i++; + } + + buf[i++] = 'D'; buf[i++] = 'A'; buf[i++] = 'T'; buf[i++] = 'E'; + } + if(data & static_cast(CheckFlags::USER)){ + if(buf[i-1] != '['){ + buf[i] = ','; + i++; + } + + buf[i++] = 'U'; buf[i++] = 'S'; buf[i++] = 'E'; buf[i++] = 'R'; + } + if(data & static_cast(CheckFlags::CERT)){ + if(buf[i-1] != '['){ + buf[i] = ','; + i++; + } + + buf[i++] = 'C'; buf[i++] = 'E'; buf[i++] = 'R'; buf[i++] = 'T'; + } + if(data & static_cast(CheckFlags::KEYS)){ + if(buf[i-1] != '['){ + buf[i] = ','; + i++; + } + + buf[i++] = 'K'; buf[i++] = 'E'; buf[i++] = 'Y'; buf[i++] = 'S'; + } + if(data & static_cast(CheckFlags::DEST)){ + if(buf[i-1] != '['){ + buf[i] = ','; + i++; + } + + buf[i++] = 'D'; buf[i++] = 'E'; buf[i++] = 'S'; buf[i++] = 'T'; + } + } + + buf[i] = ']'; + std::cout << buf; } From 3f8538b3c9283091ec335d338124a1e1f44e0882 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 10:57:16 +0500 Subject: [PATCH 16/65] Update CMakeLists.txt --- 04_week/tasks/CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/04_week/tasks/CMakeLists.txt b/04_week/tasks/CMakeLists.txt index 6ddf92b4..b42c26a7 100644 --- a/04_week/tasks/CMakeLists.txt +++ b/04_week/tasks/CMakeLists.txt @@ -1,4 +1,3 @@ add_subdirectory(stack) -add_subdirectory(queue) + add_subdirectory(ring_buffer) -add_subdirectory(phasor) \ No newline at end of file From 88dbd8a9a3dfab1cb89afb77e27545bb75d02485 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 11:27:53 +0500 Subject: [PATCH 17/65] Update tracer.cpp --- 05_week/tasks/tracer/tracer.cpp | 41 ++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/05_week/tasks/tracer/tracer.cpp b/05_week/tasks/tracer/tracer.cpp index 2ccfb417..de3fe505 100644 --- a/05_week/tasks/tracer/tracer.cpp +++ b/05_week/tasks/tracer/tracer.cpp @@ -1,6 +1,45 @@ +/* + Трассировщик +Необходимо реализовать класс Tracer, подсчитывающий вызовы своих конструкторов, операторов присваивания и деструктора. + +В качестве данных внутри класса должна храниться имя std::string и идентификатор. + +В классе присутствуют следующие счетчики, доступные извне: + +count - общее количество созданных объектов (используется для генерации id) +default_ctor - количество вызовов конструктора по умолчанию +str_ctor - количество вызовов конструктора от строки +copy_ctor - количество вызовов конструктора копирования +move_ctor - количество вызовов конструктора перемещения +copy_assign - количество вызовов оператора копирующего присваивания +move_assign - количество вызовов оператора перемещающего присваивания +dtor - количество вызовов деструктора +alive - количество живых объектов в данный момент +Правила изменения идентификатора (id): + +присваивается при создании и НЕ меняется в течение жизни объекта +каждый новый объект получает уникальный id (увеличивающийся счетчик) +при использовании операторов не изменяется +Класс предоставляет следующий функционал: + +Конструктор по умолчанию - создает объект с именем obj_{id} ("obj_1") +Конструктор от строки std::string - создает объект с именем {name}_{id} +Конструктор копирования - копирует имя, но создает id +Конструктор перемещения - перемещает имя, но создает id +Оператор присваивания копированием - копирует имя, не изменяет id +Оператор перемещения копированием - перемещает имя, не изменяет id +Деструктор - изменяет свои счетчики +Метод Id - возвращает идентификатор объекта +Метод Name - возвращает константную ссылку на имя. +Метод Data - возвращает указатель на данные строки. +Метод ResetStats - сбрасывает на 0 все счетчики +Примечание +Для удобства отладки можно написать функции, выводящие на экран статистики и логирующие действия. +*/ + #include class Tracer { -}; \ No newline at end of file +}; From b2fb4f4975c11116fe9e5a85377564426d281788 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 12:54:22 +0500 Subject: [PATCH 18/65] Update tracer.cpp Start --- 05_week/tasks/tracer/tracer.cpp | 51 +++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/05_week/tasks/tracer/tracer.cpp b/05_week/tasks/tracer/tracer.cpp index de3fe505..3af22906 100644 --- a/05_week/tasks/tracer/tracer.cpp +++ b/05_week/tasks/tracer/tracer.cpp @@ -42,4 +42,55 @@ alive - количество живых объектов в данный мом class Tracer { +public: + // static для переменных, тогда при вызове значение будет известно предыдущее значение. + static size_t count; //- общее количество созданных объектов (используется для генерации id) + static size_t default_ctor; // - количество вызовов конструктора по умолчанию + static size_t str_ctor; // - количество вызовов конструктора от строки + static size_t copy_ctor; // - количество вызовов конструктора копирования + static size_t move_ctor; // - количество вызовов конструктора перемещения + static size_t copy_assign; // - количество вызовов оператора копирующего присваивания + static size_t move_assign; // - количество вызовов оператора перемещающего присваивания + static size_t dtor; // - количество вызовов деструктора + static size_t alive; // - количество живых объектов в данный момент + + Trice(): id_(++count), name_ ("obj_" + (std::to_string(count+1))){ + ++default_ctor; + ++alive; + } + + Trice(const std::string data): id_(++count), name_ (data +"_" + (std::to_string(count+1))){ + ++default_ctor; + ++alive; + } + + + + void ResetStats() { + count = 0; + default_ctor = 0; + str_ctor = 0; + copy_ctor = 0; + move_ctor = 0; + copy_assign = 0; + move_assign = 0; + dtor = 0; + alive = 0; +} + +private: + std::string name_; + size_t id_; }; + + +// Инициализация статических членов класса +size_t Tracer::count = 0; +size_t Tracer::default_ctor = 0; +size_t Tracer::str_ctor = 0; +size_t Tracer::copy_ctor = 0; +size_t Tracer::move_ctor = 0; +size_t Tracer::copy_assign = 0; +size_t Tracer::move_assign = 0; +size_t Tracer::dtor = 0; +size_t Tracer::alive = 0; From 21116bf1b548dcd11c8d2eb822720695bc7d3df2 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 13:07:26 +0500 Subject: [PATCH 19/65] Update tracer.cpp --- 05_week/tasks/tracer/tracer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/05_week/tasks/tracer/tracer.cpp b/05_week/tasks/tracer/tracer.cpp index 3af22906..db514782 100644 --- a/05_week/tasks/tracer/tracer.cpp +++ b/05_week/tasks/tracer/tracer.cpp @@ -54,12 +54,12 @@ class Tracer { static size_t dtor; // - количество вызовов деструктора static size_t alive; // - количество живых объектов в данный момент - Trice(): id_(++count), name_ ("obj_" + (std::to_string(count+1))){ + Tracer(): id_(++count), name_ ("obj_" + (std::to_string(count+1))){ ++default_ctor; ++alive; } - Trice(const std::string data): id_(++count), name_ (data +"_" + (std::to_string(count+1))){ + Tracer(const std::string data): id_(++count), name_ (data +"_" + (std::to_string(count+1))){ ++default_ctor; ++alive; } @@ -76,7 +76,7 @@ class Tracer { move_assign = 0; dtor = 0; alive = 0; -} + } private: std::string name_; From b5f508579ab6ebf3d0713bd96362ea6e75dc251f Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 13:11:08 +0500 Subject: [PATCH 20/65] Update tracer.cpp --- 05_week/tasks/tracer/tracer.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/05_week/tasks/tracer/tracer.cpp b/05_week/tasks/tracer/tracer.cpp index db514782..c297b59a 100644 --- a/05_week/tasks/tracer/tracer.cpp +++ b/05_week/tasks/tracer/tracer.cpp @@ -40,7 +40,12 @@ alive - количество живых объектов в данный мом #include + class Tracer { +private: + size_t id_; + std::string name_; + public: // static для переменных, тогда при вызове значение будет известно предыдущее значение. @@ -78,9 +83,7 @@ class Tracer { alive = 0; } -private: - std::string name_; - size_t id_; + }; From 7f9c09ed84d1dee8d7251ef5270b4bf0f5f0cc31 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 13:16:03 +0500 Subject: [PATCH 21/65] Update tracer.cpp --- 05_week/tasks/tracer/tracer.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/05_week/tasks/tracer/tracer.cpp b/05_week/tasks/tracer/tracer.cpp index c297b59a..0243dcd5 100644 --- a/05_week/tasks/tracer/tracer.cpp +++ b/05_week/tasks/tracer/tracer.cpp @@ -69,9 +69,18 @@ class Tracer { ++alive; } - - - void ResetStats() { + // Деструктор + ~Tracer() { + ++dtor; + --alive; + } + + // Методы доступа + size_t Id() const { return id_; } + const std::string& Name() const { return name_; } + const char* Data() const { return name_.c_str(); } + + static void ResetStats() { count = 0; default_ctor = 0; str_ctor = 0; From 64e94d21dff8167e60e4c92bc02efe82f00d3435 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 13:18:08 +0500 Subject: [PATCH 22/65] Update tracer.cpp --- 05_week/tasks/tracer/tracer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/05_week/tasks/tracer/tracer.cpp b/05_week/tasks/tracer/tracer.cpp index 0243dcd5..69bf4ac7 100644 --- a/05_week/tasks/tracer/tracer.cpp +++ b/05_week/tasks/tracer/tracer.cpp @@ -59,12 +59,12 @@ class Tracer { static size_t dtor; // - количество вызовов деструктора static size_t alive; // - количество живых объектов в данный момент - Tracer(): id_(++count), name_ ("obj_" + (std::to_string(count+1))){ + Tracer(): id_(++count), name_ ("obj_" + (std::to_string(count))){ ++default_ctor; ++alive; } - Tracer(const std::string data): id_(++count), name_ (data +"_" + (std::to_string(count+1))){ + Tracer(const std::string data): id_(++count), name_ (data +"_" + (std::to_string(count))){ ++default_ctor; ++alive; } From 2c5609fceef1e02a8138061a883b3b4ca02cc0e6 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 15:39:16 +0500 Subject: [PATCH 23/65] Update tracer.cpp --- 05_week/tasks/tracer/tracer.cpp | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/05_week/tasks/tracer/tracer.cpp b/05_week/tasks/tracer/tracer.cpp index 69bf4ac7..de8d8cfb 100644 --- a/05_week/tasks/tracer/tracer.cpp +++ b/05_week/tasks/tracer/tracer.cpp @@ -64,11 +64,37 @@ class Tracer { ++alive; } - Tracer(const std::string data): id_(++count), name_ (data +"_" + (std::to_string(count))){ + Tracer(const std::string data) : id_(++count), name_ (data +"_" + (std::to_string(count))){ ++default_ctor; ++alive; } + Tracer(const Tracer& data) : id_(++count), name_(data.name_) { + ++copy_ctor; + ++alive; + } + + Tracer(Tracer&& other) : id_(++count), name_(std::move(other.name_)){ + ++move_ctor; + ++alive; + } + + Tracer& operator=(const Tracer& data) { // копирует имя, не изменяет id + if (this != &data) { + name_ = data.name_; + ++copy_assign; + } + return *this; + } + + Tracer& operator=(Tracer&& data) { // перемещает имя, не изменяет id + if (this != &data) { + name_ = std::move(other.name_); + ++move_assign; + } + return *this; + } + // Деструктор ~Tracer() { ++dtor; From f290d2f9d8b13cc559247736f2ae2f531f6d7589 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 15:40:31 +0500 Subject: [PATCH 24/65] Update tracer.cpp --- 05_week/tasks/tracer/tracer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/05_week/tasks/tracer/tracer.cpp b/05_week/tasks/tracer/tracer.cpp index de8d8cfb..b4677332 100644 --- a/05_week/tasks/tracer/tracer.cpp +++ b/05_week/tasks/tracer/tracer.cpp @@ -74,7 +74,7 @@ class Tracer { ++alive; } - Tracer(Tracer&& other) : id_(++count), name_(std::move(other.name_)){ + Tracer(Tracer&& other) : id_(++count), name_(std::move(data.name_)){ ++move_ctor; ++alive; } From d6735e479a5e77ecdc45fa7200c992aa7a2f0f8e Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 16:27:03 +0500 Subject: [PATCH 25/65] Update tracer.cpp --- 05_week/tasks/tracer/tracer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/05_week/tasks/tracer/tracer.cpp b/05_week/tasks/tracer/tracer.cpp index b4677332..4e38b493 100644 --- a/05_week/tasks/tracer/tracer.cpp +++ b/05_week/tasks/tracer/tracer.cpp @@ -74,7 +74,7 @@ class Tracer { ++alive; } - Tracer(Tracer&& other) : id_(++count), name_(std::move(data.name_)){ + Tracer(Tracer&& data) : id_(++count), name_(std::move(data.name_)){ ++move_ctor; ++alive; } @@ -89,7 +89,7 @@ class Tracer { Tracer& operator=(Tracer&& data) { // перемещает имя, не изменяет id if (this != &data) { - name_ = std::move(other.name_); + name_ = std::move(data.name_); ++move_assign; } return *this; From 0ed30da39225fa034bf95e2237d963e762352719 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 16:32:35 +0500 Subject: [PATCH 26/65] Update tracer.cpp --- 05_week/tasks/tracer/tracer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/05_week/tasks/tracer/tracer.cpp b/05_week/tasks/tracer/tracer.cpp index 4e38b493..a4c0d373 100644 --- a/05_week/tasks/tracer/tracer.cpp +++ b/05_week/tasks/tracer/tracer.cpp @@ -65,7 +65,7 @@ class Tracer { } Tracer(const std::string data) : id_(++count), name_ (data +"_" + (std::to_string(count))){ - ++default_ctor; + ++str_ctor; ++alive; } From 9f20ad55205232d16a9dc25f9b478a6de5b73f22 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 16:44:56 +0500 Subject: [PATCH 27/65] Update tracer.cpp --- 05_week/tasks/tracer/tracer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/05_week/tasks/tracer/tracer.cpp b/05_week/tasks/tracer/tracer.cpp index a4c0d373..631a2d43 100644 --- a/05_week/tasks/tracer/tracer.cpp +++ b/05_week/tasks/tracer/tracer.cpp @@ -70,7 +70,7 @@ class Tracer { } Tracer(const Tracer& data) : id_(++count), name_(data.name_) { - ++copy_ctor; + ++move_ctor; ++alive; } From 7b7d988056515498686c5f26b45f46e8502201d4 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 16:46:15 +0500 Subject: [PATCH 28/65] Update tracer.cpp --- 05_week/tasks/tracer/tracer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/05_week/tasks/tracer/tracer.cpp b/05_week/tasks/tracer/tracer.cpp index 631a2d43..a4c0d373 100644 --- a/05_week/tasks/tracer/tracer.cpp +++ b/05_week/tasks/tracer/tracer.cpp @@ -70,7 +70,7 @@ class Tracer { } Tracer(const Tracer& data) : id_(++count), name_(data.name_) { - ++move_ctor; + ++copy_ctor; ++alive; } From b2bc06fbb35ead2e21d48ed8ef7a6b242bf737b8 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 16:50:24 +0500 Subject: [PATCH 29/65] Update tracer.cpp --- 05_week/tasks/tracer/tracer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/05_week/tasks/tracer/tracer.cpp b/05_week/tasks/tracer/tracer.cpp index a4c0d373..bc509f0d 100644 --- a/05_week/tasks/tracer/tracer.cpp +++ b/05_week/tasks/tracer/tracer.cpp @@ -74,7 +74,7 @@ class Tracer { ++alive; } - Tracer(Tracer&& data) : id_(++count), name_(std::move(data.name_)){ + Tracer(Tracer&& data) noexcept : id_(++count), name_(std::move(data.name_)){ ++move_ctor; ++alive; } From 8fc188ca3780a96e24946d12d4e242deb0e3bf4e Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 22:20:37 +0500 Subject: [PATCH 30/65] Update string_view.cpp --- 05_week/tasks/string_view/string_view.cpp | 164 +++++++++++++++++++++- 1 file changed, 163 insertions(+), 1 deletion(-) diff --git a/05_week/tasks/string_view/string_view.cpp b/05_week/tasks/string_view/string_view.cpp index 438c4536..c1f5e5c8 100644 --- a/05_week/tasks/string_view/string_view.cpp +++ b/05_week/tasks/string_view/string_view.cpp @@ -1,7 +1,169 @@ +/* + Представление строки + Необходимо реализовать класс StringView, представляющий упрощенную реализацию std::string_view. В отличие от std::string данный класс не владеет строкой (ресурсами), а хранит лишь размер и указатель на начало строки. Это позволяет быстро создавать представление строки, копировать и создавать подстроки. Важно понимать, что поскольку StringView не владеет строкой, а лишь наблюдает за оригинальной строкой, то при изменении оригинала представление тоже изменится. При этом сам класс StringView не может изменять строку, за которой наблюдает. + + Класс предоставляет следующий функционал: + + Конструктор от std::string, позиции начала подстроки (по умолчанию 0) и длину наблюдаемой подстроки (по умолчанию аналог std::string::npos). Длину подстроки следует обрезать, если она превышает длину строки. Если начало превышает длину, то следует создать StringView с параметрами по умолчанию + Конструктор от C-строки + Конструктор от C-строки и длины + Оператор [] - доступ на чтение символа + Метод Data - возвращает указатель на начало наблюдаемой строки + Метод Front - доступ на чтение к первому символу. + Метод Back - доступ на чтение к последнему символу. + Методы Size, Length - возвращают длину наблюдаемой строки + Метод Empty - проверяет на пустоту + Метод RemovePrefix - убирает заданное количество символов из начала представления + Метод RemoveSuffix - убирает заданное количество символов с конца представления + Метод Substr - может принимать позицию начала поиска и количество элементов и возвращает StringView. В случае, когда подстрока начала поиска превышает длину строки, следует вернуть пустое представление + Метод Find - принимает символ или StringView и позицию начала поиска (по умолчанию 0), возвращает позицию начала совпадения элемента (или аналог std::string::npos) + Метод ToString - создает std::string на основе представления + Примечание + Запрещено использовать std::string_view в реализации + Передавать std::string по значению в первый конструктор очень плохая идея + Получить длину C-строки можно с помощью функции strlen. + Не забудьте про константность методов +*/ + + #include #include class StringView { -}; \ No newline at end of file +private: + const char* data_; + size_t size_; + +public: + + StringView() : data_(nullptr), size_(0) {} // Конструктор по умолчанию + +/* + Конструктор от std::string, позиции начала подстроки (по умолчанию 0) и длину наблюдаемой подстроки (по умолчанию аналог std::string::npos). + Длину подстроки следует обрезать, если она превышает длину строки. Если начало превышает длину, то следует создать StringView с параметрами по умолчанию +*/ + StringView(const std::string& str, size_t pos = 0, size_t len = -1) { // -1 т.к. цитата "Константа объявлена как -1. Это связано с тем, что size_t — тип беззнакового целого числа, и -1 — наибольшее возможное представимое значение для этого типа." + if(str.size() <= pos) // проверка, что длина строки больше чем позиция начала. + { + data_ = nullptr; + size_ = 0; + return; + } + + data_ = str.data() + pos; + // проверка, что длина + позиция не выходят за размер строки + if(len+pos >= str.size()) size_ = str.size() - pos; // вышли, обризаем длину + else size_ = len; + } + +//Конструктор от C-строки + StringView(const char* str){ + if (str == nullptr) { // проверка на пустую строку + data_ = nullptr; + size_ = 0; + return; + } + + data_ = str; + size_ = std::strlen(str); // расчет схдлины строки средством strlen + } + + +//Конструктор от C-строки и длины + StringView(const char* str, size_t len){ + if (str == nullptr) { // проверка на пустую строку + data_ = nullptr; + size_ = 0; + return; + } + // проверки на 0ю длину строки нет т.к. 0 - валидная длина. + data_ = str; + size_ = len; + } + +//Оператор [] - доступ на чтение символа +char operator[](size_t pos) const { return data_[pos]; } + +//Метод Data - возвращает указатель на начало наблюдаемой строки +const char* Data() const { return data_; } + +// Метод Front - доступ на чтение к первому символу. +char Front() const { return data_[0]; } + +// Метод Back - доступ на чтение к последнему символу. +char Back() const { return data_[size_ -1]; } + +// Методы Size, Length - возвращают длину наблюдаемой строки + size_t Size() const { return size_;} + size_t Length() const { return size_; } + +// Метод Empty - проверяет на пустоту + bool Empty() const { + if(size_ == 0) return true; + return false; + } + +// Метод RemovePrefix - убирает заданное количество символов из начала представления + void RemovePrefix(size_t len) { // по идее тут надо проверить кооректность, а именно что длина должна быть меньше size_ len + data_ += len; + size_ -= len; + } + +// Метод RemoveSuffix - убирает заданное количество символов с конца представления + void RemoveSuffix(size_t n) { size_ -= n; } + +// Метод Substr - может принимать позицию начала поиска и количество элементов и возвращает StringView. В случае, когда подстрока начала поиска превышает длину строки, следует вернуть пустое представление + StringView Substr(size_t pos = 0, size_t len = -1) const { + if (pos >= size_) { return StringView(); } // В случае, когда подстрока начала поиска превышает длину строки, следует вернуть пустое представление + + size_ = size_ - pos; + if ((len != -1) && (len < new_size)) size_ = count; + + return StringView(data_ + pos, size_); + } +// Метод Find - принимает символ или StringView и позицию начала поиска (по умолчанию 0), возвращает позицию начала совпадения элемента (или аналог std::string::npos) + + size_t Find(char symb, size_t pos = 0) const { + + for (size_t i = pos; i < size_; ++i) { + if (data_[i] == symb) return i; + } + + return -1; //не совпало + } +// переопределение Find ддля строки + size_t Find(const StringView& str, size_t pos = 0) const { + if ((pos >= size_) || ((pos + sv.ize_) >= size_)) return -1; + + if (str.Empty()) return -1; + + siz_t i = pos; // индекс проверяемой позиции + siz_t j = 0; // счетчик совпадений + + while(i < size_) // првоеряемая должна быть меньше размера строки + { + if(str.data_[j] == data_[i]) j++; // элементы совпали, инкриментируем счетчик совпадений + else j = 0; + + if(j == str.size_) return i; // длина строки совпала с количеством совпадений, значит нашли совпадение + + i++; + } + + return -1; + } + + // Преобразование в std::string + std::string ToString() const { + if (data_ == nullptr || size_ == 0) { + return std::string(); + } + return std::string(data_, size_); + } + + + + +}; From c290dc0f75dd11a4a01d5ef988b8029c5c1cfb3e Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 22:24:29 +0500 Subject: [PATCH 31/65] Update string_view.cpp --- 05_week/tasks/string_view/string_view.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/05_week/tasks/string_view/string_view.cpp b/05_week/tasks/string_view/string_view.cpp index c1f5e5c8..b1f0eb37 100644 --- a/05_week/tasks/string_view/string_view.cpp +++ b/05_week/tasks/string_view/string_view.cpp @@ -118,10 +118,10 @@ char Back() const { return data_[size_ -1]; } StringView Substr(size_t pos = 0, size_t len = -1) const { if (pos >= size_) { return StringView(); } // В случае, когда подстрока начала поиска превышает длину строки, следует вернуть пустое представление - size_ = size_ - pos; - if ((len != -1) && (len < new_size)) size_ = count; + size_t newSize = size_ - pos; + if ((len != -1) && (len < newSize)) newSize = count; - return StringView(data_ + pos, size_); + return StringView(data_ + pos, newSize); } // Метод Find - принимает символ или StringView и позицию начала поиска (по умолчанию 0), возвращает позицию начала совпадения элемента (или аналог std::string::npos) @@ -139,8 +139,8 @@ char Back() const { return data_[size_ -1]; } if (str.Empty()) return -1; - siz_t i = pos; // индекс проверяемой позиции - siz_t j = 0; // счетчик совпадений + size_t i = pos; // индекс проверяемой позиции + size_t j = 0; // счетчик совпадений while(i < size_) // првоеряемая должна быть меньше размера строки { From 62c61c8a866c55359544819e2c078047a908fe94 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 22:28:28 +0500 Subject: [PATCH 32/65] Update string_view.cpp --- 05_week/tasks/string_view/string_view.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/05_week/tasks/string_view/string_view.cpp b/05_week/tasks/string_view/string_view.cpp index b1f0eb37..b6b65487 100644 --- a/05_week/tasks/string_view/string_view.cpp +++ b/05_week/tasks/string_view/string_view.cpp @@ -37,7 +37,7 @@ class StringView { size_t size_; public: - + StringView() : data_(nullptr), size_(0) {} // Конструктор по умолчанию /* @@ -115,11 +115,11 @@ char Back() const { return data_[size_ -1]; } void RemoveSuffix(size_t n) { size_ -= n; } // Метод Substr - может принимать позицию начала поиска и количество элементов и возвращает StringView. В случае, когда подстрока начала поиска превышает длину строки, следует вернуть пустое представление - StringView Substr(size_t pos = 0, size_t len = -1) const { + StringView Substr(size_t pos = 0, size_t len = static_cast(-1)) const { if (pos >= size_) { return StringView(); } // В случае, когда подстрока начала поиска превышает длину строки, следует вернуть пустое представление size_t newSize = size_ - pos; - if ((len != -1) && (len < newSize)) newSize = count; + if ((len != static_cast(-1)) && (len < newSize)) newSize = count; return StringView(data_ + pos, newSize); } @@ -131,13 +131,13 @@ char Back() const { return data_[size_ -1]; } if (data_[i] == symb) return i; } - return -1; //не совпало + return static_cast(-1); //не совпало } // переопределение Find ддля строки size_t Find(const StringView& str, size_t pos = 0) const { - if ((pos >= size_) || ((pos + sv.ize_) >= size_)) return -1; + if ((pos >= size_) || ((pos + str.ize_) >= size_)) return static_cast(-1); - if (str.Empty()) return -1; + if (str.Empty()) return static_cast(-1); size_t i = pos; // индекс проверяемой позиции size_t j = 0; // счетчик совпадений @@ -152,7 +152,7 @@ char Back() const { return data_[size_ -1]; } i++; } - return -1; + return static_cast(-1); } // Преобразование в std::string From 4b81ccac50ea356171aabc5cf7cb465190fa60af Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 22:32:02 +0500 Subject: [PATCH 33/65] Update string_view.cpp --- 05_week/tasks/string_view/string_view.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/05_week/tasks/string_view/string_view.cpp b/05_week/tasks/string_view/string_view.cpp index b6b65487..08fdd48b 100644 --- a/05_week/tasks/string_view/string_view.cpp +++ b/05_week/tasks/string_view/string_view.cpp @@ -37,14 +37,16 @@ class StringView { size_t size_; public: + static const size_t maxVal = static_cast(-1); StringView() : data_(nullptr), size_(0) {} // Конструктор по умолчанию + /* Конструктор от std::string, позиции начала подстроки (по умолчанию 0) и длину наблюдаемой подстроки (по умолчанию аналог std::string::npos). Длину подстроки следует обрезать, если она превышает длину строки. Если начало превышает длину, то следует создать StringView с параметрами по умолчанию */ - StringView(const std::string& str, size_t pos = 0, size_t len = -1) { // -1 т.к. цитата "Константа объявлена как -1. Это связано с тем, что size_t — тип беззнакового целого числа, и -1 — наибольшее возможное представимое значение для этого типа." + StringView(const std::string& str, size_t pos = 0, size_t len = maxVal) { // -1 т.к. цитата "Константа объявлена как -1. Это связано с тем, что size_t — тип беззнакового целого числа, и -1 — наибольшее возможное представимое значение для этого типа." if(str.size() <= pos) // проверка, что длина строки больше чем позиция начала. { data_ = nullptr; @@ -115,11 +117,11 @@ char Back() const { return data_[size_ -1]; } void RemoveSuffix(size_t n) { size_ -= n; } // Метод Substr - может принимать позицию начала поиска и количество элементов и возвращает StringView. В случае, когда подстрока начала поиска превышает длину строки, следует вернуть пустое представление - StringView Substr(size_t pos = 0, size_t len = static_cast(-1)) const { + StringView Substr(size_t pos = 0, size_t len = maxVal) const { if (pos >= size_) { return StringView(); } // В случае, когда подстрока начала поиска превышает длину строки, следует вернуть пустое представление size_t newSize = size_ - pos; - if ((len != static_cast(-1)) && (len < newSize)) newSize = count; + if ((len != maxVal) && (len < newSize)) newSize = count; return StringView(data_ + pos, newSize); } @@ -131,13 +133,13 @@ char Back() const { return data_[size_ -1]; } if (data_[i] == symb) return i; } - return static_cast(-1); //не совпало + return maxVal; //не совпало } // переопределение Find ддля строки size_t Find(const StringView& str, size_t pos = 0) const { - if ((pos >= size_) || ((pos + str.ize_) >= size_)) return static_cast(-1); + if ((pos >= size_) || ((pos + str.ize_) >= size_)) return maxVal; - if (str.Empty()) return static_cast(-1); + if (str.Empty()) return maxVal; size_t i = pos; // индекс проверяемой позиции size_t j = 0; // счетчик совпадений @@ -152,7 +154,7 @@ char Back() const { return data_[size_ -1]; } i++; } - return static_cast(-1); + return maxVal; } // Преобразование в std::string From bb8100aa6c26a3e9d1735d7fe31a3469ea857290 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 22:38:09 +0500 Subject: [PATCH 34/65] Update string_view.cpp --- 05_week/tasks/string_view/string_view.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/05_week/tasks/string_view/string_view.cpp b/05_week/tasks/string_view/string_view.cpp index 08fdd48b..ee014f15 100644 --- a/05_week/tasks/string_view/string_view.cpp +++ b/05_week/tasks/string_view/string_view.cpp @@ -37,7 +37,7 @@ class StringView { size_t size_; public: - static const size_t maxVal = static_cast(-1); + static const size_t npos = static_cast(-1); StringView() : data_(nullptr), size_(0) {} // Конструктор по умолчанию @@ -46,7 +46,7 @@ class StringView { Конструктор от std::string, позиции начала подстроки (по умолчанию 0) и длину наблюдаемой подстроки (по умолчанию аналог std::string::npos). Длину подстроки следует обрезать, если она превышает длину строки. Если начало превышает длину, то следует создать StringView с параметрами по умолчанию */ - StringView(const std::string& str, size_t pos = 0, size_t len = maxVal) { // -1 т.к. цитата "Константа объявлена как -1. Это связано с тем, что size_t — тип беззнакового целого числа, и -1 — наибольшее возможное представимое значение для этого типа." + StringView(const std::string& str, size_t pos = 0, size_t len = npos) { // -1 т.к. цитата "Константа объявлена как -1. Это связано с тем, что size_t — тип беззнакового целого числа, и -1 — наибольшее возможное представимое значение для этого типа." if(str.size() <= pos) // проверка, что длина строки больше чем позиция начала. { data_ = nullptr; @@ -117,11 +117,11 @@ char Back() const { return data_[size_ -1]; } void RemoveSuffix(size_t n) { size_ -= n; } // Метод Substr - может принимать позицию начала поиска и количество элементов и возвращает StringView. В случае, когда подстрока начала поиска превышает длину строки, следует вернуть пустое представление - StringView Substr(size_t pos = 0, size_t len = maxVal) const { + StringView Substr(size_t pos = 0, size_t len = npos) const { if (pos >= size_) { return StringView(); } // В случае, когда подстрока начала поиска превышает длину строки, следует вернуть пустое представление size_t newSize = size_ - pos; - if ((len != maxVal) && (len < newSize)) newSize = count; + if ((len != npos) && (len < newSize)) newSize = len; return StringView(data_ + pos, newSize); } @@ -132,14 +132,15 @@ char Back() const { return data_[size_ -1]; } for (size_t i = pos; i < size_; ++i) { if (data_[i] == symb) return i; } + - return maxVal; //не совпало + return npos; //не совпало } // переопределение Find ддля строки size_t Find(const StringView& str, size_t pos = 0) const { - if ((pos >= size_) || ((pos + str.ize_) >= size_)) return maxVal; + if ((pos >= size_) || ((pos + str.size_) >= size_)) return npos; - if (str.Empty()) return maxVal; + if (str.Empty()) return npos; size_t i = pos; // индекс проверяемой позиции size_t j = 0; // счетчик совпадений @@ -154,7 +155,7 @@ char Back() const { return data_[size_ -1]; } i++; } - return maxVal; + return npos; } // Преобразование в std::string From c2f00c1af97e84ac950976c21e4c2dbf1eea3001 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 22:41:37 +0500 Subject: [PATCH 35/65] Update string_view.cpp --- 05_week/tasks/string_view/string_view.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/05_week/tasks/string_view/string_view.cpp b/05_week/tasks/string_view/string_view.cpp index ee014f15..af8fbb0d 100644 --- a/05_week/tasks/string_view/string_view.cpp +++ b/05_week/tasks/string_view/string_view.cpp @@ -37,7 +37,7 @@ class StringView { size_t size_; public: - static const size_t npos = static_cast(-1); + static const size_t npos = std::string_view::npos; StringView() : data_(nullptr), size_(0) {} // Конструктор по умолчанию From 39b43cd3fff2ea49649e1bc4742fa9d400adc304 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 22:43:01 +0500 Subject: [PATCH 36/65] Update string_view.cpp --- 05_week/tasks/string_view/string_view.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/05_week/tasks/string_view/string_view.cpp b/05_week/tasks/string_view/string_view.cpp index af8fbb0d..d52e5aaa 100644 --- a/05_week/tasks/string_view/string_view.cpp +++ b/05_week/tasks/string_view/string_view.cpp @@ -37,7 +37,7 @@ class StringView { size_t size_; public: - static const size_t npos = std::string_view::npos; + inline static const size_t npos = static_cast(-1); StringView() : data_(nullptr), size_(0) {} // Конструктор по умолчанию From 825da8f2ce7bc9c431ce3b105e940713c7ed4bb3 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 22:50:59 +0500 Subject: [PATCH 37/65] Update string_view.cpp --- 05_week/tasks/string_view/string_view.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/05_week/tasks/string_view/string_view.cpp b/05_week/tasks/string_view/string_view.cpp index d52e5aaa..bff85203 100644 --- a/05_week/tasks/string_view/string_view.cpp +++ b/05_week/tasks/string_view/string_view.cpp @@ -109,8 +109,14 @@ char Back() const { return data_[size_ -1]; } // Метод RemovePrefix - убирает заданное количество символов из начала представления void RemovePrefix(size_t len) { // по идее тут надо проверить кооректность, а именно что длина должна быть меньше size_ len - data_ += len; - size_ -= len; + if (len >= size_) { + data_ = nullptr; + size_ = 0; + } + else { + data_ += len; + size_ -= len; + } } // Метод RemoveSuffix - убирает заданное количество символов с конца представления @@ -150,7 +156,7 @@ char Back() const { return data_[size_ -1]; } if(str.data_[j] == data_[i]) j++; // элементы совпали, инкриментируем счетчик совпадений else j = 0; - if(j == str.size_) return i; // длина строки совпала с количеством совпадений, значит нашли совпадение + if(j == str.size_) return i-j; // длина строки совпала с количеством совпадений, значит нашли совпадение i++; } From dc221387c4a7fe8b5b197be26e5e72cc89a44a6c Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 23:03:10 +0500 Subject: [PATCH 38/65] Update string_view.cpp --- 05_week/tasks/string_view/string_view.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/05_week/tasks/string_view/string_view.cpp b/05_week/tasks/string_view/string_view.cpp index bff85203..d711d983 100644 --- a/05_week/tasks/string_view/string_view.cpp +++ b/05_week/tasks/string_view/string_view.cpp @@ -53,11 +53,12 @@ class StringView { size_ = 0; return; } - + data_ = str.data() + pos; - // проверка, что длина + позиция не выходят за размер строки - if(len+pos >= str.size()) size_ = str.size() - pos; // вышли, обризаем длину - else size_ = len; + + size_t maxLen = str.size() - pos; + if ((len == npos) || (len > maxLen)) size_ = maxLen; // вышли, обризаем длину + else size_ = len; } //Конструктор от C-строки @@ -120,7 +121,14 @@ char Back() const { return data_[size_ -1]; } } // Метод RemoveSuffix - убирает заданное количество символов с конца представления - void RemoveSuffix(size_t n) { size_ -= n; } + void RemoveSuffix(size_t len) { + if (len >= size_) { + data_ = nullptr; + size_ = 0; + } + else size_ -= len; + + } // Метод Substr - может принимать позицию начала поиска и количество элементов и возвращает StringView. В случае, когда подстрока начала поиска превышает длину строки, следует вернуть пустое представление StringView Substr(size_t pos = 0, size_t len = npos) const { From 90ba0786c287864acc368caf58456eb049bb0949 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 23:06:13 +0500 Subject: [PATCH 39/65] Update string_view.cpp --- 05_week/tasks/string_view/string_view.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/05_week/tasks/string_view/string_view.cpp b/05_week/tasks/string_view/string_view.cpp index d711d983..aa259bbc 100644 --- a/05_week/tasks/string_view/string_view.cpp +++ b/05_week/tasks/string_view/string_view.cpp @@ -164,7 +164,7 @@ char Back() const { return data_[size_ -1]; } if(str.data_[j] == data_[i]) j++; // элементы совпали, инкриментируем счетчик совпадений else j = 0; - if(j == str.size_) return i-j; // длина строки совпала с количеством совпадений, значит нашли совпадение + if(j == str.size_) return i-j+1; // длина строки совпала с количеством совпадений, значит нашли совпадение i++; } From 95d600ec2c74fa34b4004fefe61dec0986d282e8 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 23:08:20 +0500 Subject: [PATCH 40/65] Update string_view.cpp --- 05_week/tasks/string_view/string_view.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/05_week/tasks/string_view/string_view.cpp b/05_week/tasks/string_view/string_view.cpp index aa259bbc..17118991 100644 --- a/05_week/tasks/string_view/string_view.cpp +++ b/05_week/tasks/string_view/string_view.cpp @@ -152,8 +152,9 @@ char Back() const { return data_[size_ -1]; } } // переопределение Find ддля строки size_t Find(const StringView& str, size_t pos = 0) const { - if ((pos >= size_) || ((pos + str.size_) >= size_)) return npos; - + if ((pos >= size_) || ((pos + str.size_) >= size_) || (str.Empty())) return npos; + + } if (str.Empty()) return npos; size_t i = pos; // индекс проверяемой позиции From 3349f8875244ba92ce3c02a4f3d7c5ee30f34e37 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 23:10:37 +0500 Subject: [PATCH 41/65] Update string_view.cpp --- 05_week/tasks/string_view/string_view.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/05_week/tasks/string_view/string_view.cpp b/05_week/tasks/string_view/string_view.cpp index 17118991..accb4a27 100644 --- a/05_week/tasks/string_view/string_view.cpp +++ b/05_week/tasks/string_view/string_view.cpp @@ -154,7 +154,6 @@ char Back() const { return data_[size_ -1]; } size_t Find(const StringView& str, size_t pos = 0) const { if ((pos >= size_) || ((pos + str.size_) >= size_) || (str.Empty())) return npos; - } if (str.Empty()) return npos; size_t i = pos; // индекс проверяемой позиции From d483901867cc73e0fd90b991f2874738f5e70a04 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Fri, 13 Feb 2026 23:14:01 +0500 Subject: [PATCH 42/65] Update string_view.cpp --- 05_week/tasks/string_view/string_view.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/05_week/tasks/string_view/string_view.cpp b/05_week/tasks/string_view/string_view.cpp index accb4a27..6b978760 100644 --- a/05_week/tasks/string_view/string_view.cpp +++ b/05_week/tasks/string_view/string_view.cpp @@ -152,9 +152,9 @@ char Back() const { return data_[size_ -1]; } } // переопределение Find ддля строки size_t Find(const StringView& str, size_t pos = 0) const { - if ((pos >= size_) || ((pos + str.size_) >= size_) || (str.Empty())) return npos; - - if (str.Empty()) return npos; + if ((pos >= size_) || ((pos + str.size_) >= size_)) return npos; + + if(str.Empty()) return 0; size_t i = pos; // индекс проверяемой позиции size_t j = 0; // счетчик совпадений From 90bf55a75da53ef8a6932e95b4bd14fb93ba86ab Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Mon, 16 Feb 2026 11:56:59 +0500 Subject: [PATCH 43/65] Update string_view.cpp --- 05_week/tasks/string_view/string_view.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/05_week/tasks/string_view/string_view.cpp b/05_week/tasks/string_view/string_view.cpp index 6b978760..59f668d3 100644 --- a/05_week/tasks/string_view/string_view.cpp +++ b/05_week/tasks/string_view/string_view.cpp @@ -154,7 +154,7 @@ char Back() const { return data_[size_ -1]; } size_t Find(const StringView& str, size_t pos = 0) const { if ((pos >= size_) || ((pos + str.size_) >= size_)) return npos; - if(str.Empty()) return 0; + if(str.Empty()) return npos; size_t i = pos; // индекс проверяемой позиции size_t j = 0; // счетчик совпадений From 0129bf9eea7aef38506df3917b165b8d538279f1 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Mon, 16 Feb 2026 11:59:07 +0500 Subject: [PATCH 44/65] Update string_view.cpp --- 05_week/tasks/string_view/string_view.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/05_week/tasks/string_view/string_view.cpp b/05_week/tasks/string_view/string_view.cpp index 59f668d3..c1fa1207 100644 --- a/05_week/tasks/string_view/string_view.cpp +++ b/05_week/tasks/string_view/string_view.cpp @@ -148,13 +148,13 @@ char Back() const { return data_[size_ -1]; } } - return npos; //не совпало + return 0; //не совпало } // переопределение Find ддля строки size_t Find(const StringView& str, size_t pos = 0) const { if ((pos >= size_) || ((pos + str.size_) >= size_)) return npos; - if(str.Empty()) return npos; + if(str.Empty()) return 0; size_t i = pos; // индекс проверяемой позиции size_t j = 0; // счетчик совпадений From e7a712d09ac599ca166eb42f1f5afea216c21f10 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Mon, 16 Feb 2026 12:02:42 +0500 Subject: [PATCH 45/65] Update string_view.cpp --- 05_week/tasks/string_view/string_view.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/05_week/tasks/string_view/string_view.cpp b/05_week/tasks/string_view/string_view.cpp index c1fa1207..7a9c0668 100644 --- a/05_week/tasks/string_view/string_view.cpp +++ b/05_week/tasks/string_view/string_view.cpp @@ -142,13 +142,13 @@ char Back() const { return data_[size_ -1]; } // Метод Find - принимает символ или StringView и позицию начала поиска (по умолчанию 0), возвращает позицию начала совпадения элемента (или аналог std::string::npos) size_t Find(char symb, size_t pos = 0) const { - + if(str.Empty()) return 0; for (size_t i = pos; i < size_; ++i) { if (data_[i] == symb) return i; } - return 0; //не совпало + return npos; //не совпало } // переопределение Find ддля строки size_t Find(const StringView& str, size_t pos = 0) const { From 228bae7ab35a3ff545f59c3f7989d011c4592e91 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Mon, 16 Feb 2026 12:04:11 +0500 Subject: [PATCH 46/65] Update string_view.cpp --- 05_week/tasks/string_view/string_view.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/05_week/tasks/string_view/string_view.cpp b/05_week/tasks/string_view/string_view.cpp index 7a9c0668..22194394 100644 --- a/05_week/tasks/string_view/string_view.cpp +++ b/05_week/tasks/string_view/string_view.cpp @@ -142,7 +142,7 @@ char Back() const { return data_[size_ -1]; } // Метод Find - принимает символ или StringView и позицию начала поиска (по умолчанию 0), возвращает позицию начала совпадения элемента (или аналог std::string::npos) size_t Find(char symb, size_t pos = 0) const { - if(str.Empty()) return 0; + for (size_t i = pos; i < size_; ++i) { if (data_[i] == symb) return i; } From 88ee54a9e6b34db69c625fe439eac2ef8be4d473 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Mon, 16 Feb 2026 12:08:39 +0500 Subject: [PATCH 47/65] Update string_view.cpp --- 05_week/tasks/string_view/string_view.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/05_week/tasks/string_view/string_view.cpp b/05_week/tasks/string_view/string_view.cpp index 22194394..eb6f2264 100644 --- a/05_week/tasks/string_view/string_view.cpp +++ b/05_week/tasks/string_view/string_view.cpp @@ -154,7 +154,7 @@ char Back() const { return data_[size_ -1]; } size_t Find(const StringView& str, size_t pos = 0) const { if ((pos >= size_) || ((pos + str.size_) >= size_)) return npos; - if(str.Empty()) return 0; + if(str.Empty()) return (pos <= size_) ? pos : npos; size_t i = pos; // индекс проверяемой позиции size_t j = 0; // счетчик совпадений @@ -180,7 +180,4 @@ char Back() const { return data_[size_ -1]; } return std::string(data_, size_); } - - - }; From 677d0ee2e5c479d5f0ade7b87ec22d419a4ea4a1 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Mon, 16 Feb 2026 12:11:25 +0500 Subject: [PATCH 48/65] Update string_view.cpp --- 05_week/tasks/string_view/string_view.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/05_week/tasks/string_view/string_view.cpp b/05_week/tasks/string_view/string_view.cpp index eb6f2264..32f532bf 100644 --- a/05_week/tasks/string_view/string_view.cpp +++ b/05_week/tasks/string_view/string_view.cpp @@ -154,7 +154,10 @@ char Back() const { return data_[size_ -1]; } size_t Find(const StringView& str, size_t pos = 0) const { if ((pos >= size_) || ((pos + str.size_) >= size_)) return npos; - if(str.Empty()) return (pos <= size_) ? pos : npos; + if(str.Empty()) return{ + if(pos == 0) return 0; + return npos; + } size_t i = pos; // индекс проверяемой позиции size_t j = 0; // счетчик совпадений From 2d5db4b6cb62d5b4b2c9fb95ef6b6a9d1b923f01 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Mon, 16 Feb 2026 12:12:51 +0500 Subject: [PATCH 49/65] Update string_view.cpp --- 05_week/tasks/string_view/string_view.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/05_week/tasks/string_view/string_view.cpp b/05_week/tasks/string_view/string_view.cpp index 32f532bf..87626bf3 100644 --- a/05_week/tasks/string_view/string_view.cpp +++ b/05_week/tasks/string_view/string_view.cpp @@ -154,7 +154,7 @@ char Back() const { return data_[size_ -1]; } size_t Find(const StringView& str, size_t pos = 0) const { if ((pos >= size_) || ((pos + str.size_) >= size_)) return npos; - if(str.Empty()) return{ + if(str.Empty()) { if(pos == 0) return 0; return npos; } From 18470cd611f2dbaffba6bc329b17f10c905dabd1 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Mon, 16 Feb 2026 12:18:41 +0500 Subject: [PATCH 50/65] Update string_view.cpp --- 05_week/tasks/string_view/string_view.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/05_week/tasks/string_view/string_view.cpp b/05_week/tasks/string_view/string_view.cpp index 87626bf3..930c46bd 100644 --- a/05_week/tasks/string_view/string_view.cpp +++ b/05_week/tasks/string_view/string_view.cpp @@ -153,11 +153,12 @@ char Back() const { return data_[size_ -1]; } // переопределение Find ддля строки size_t Find(const StringView& str, size_t pos = 0) const { if ((pos >= size_) || ((pos + str.size_) >= size_)) return npos; - - if(str.Empty()) { - if(pos == 0) return 0; - return npos; - } + + // Проверка пустого указателя + if (str.Empty()) return (pos <= size_) ? pos : npos; + + // Проверка границы и позиции + if (pos >= size_ || str.size_ > size_ - pos) return npos; size_t i = pos; // индекс проверяемой позиции size_t j = 0; // счетчик совпадений From 01f1e641738f8a5522855ebfbf29b9da1649b206 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Mon, 16 Feb 2026 12:24:33 +0500 Subject: [PATCH 51/65] Update string_view.cpp --- 05_week/tasks/string_view/string_view.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/05_week/tasks/string_view/string_view.cpp b/05_week/tasks/string_view/string_view.cpp index 930c46bd..2df4e4ec 100644 --- a/05_week/tasks/string_view/string_view.cpp +++ b/05_week/tasks/string_view/string_view.cpp @@ -152,13 +152,13 @@ char Back() const { return data_[size_ -1]; } } // переопределение Find ддля строки size_t Find(const StringView& str, size_t pos = 0) const { - if ((pos >= size_) || ((pos + str.size_) >= size_)) return npos; + // Проверка пустого указателя if (str.Empty()) return (pos <= size_) ? pos : npos; // Проверка границы и позиции - if (pos >= size_ || str.size_ > size_ - pos) return npos; + if ((pos >= size_) || ((pos + str.size_) >= size_)) return npos; size_t i = pos; // индекс проверяемой позиции size_t j = 0; // счетчик совпадений From a9aac500a0984eed896f77ee45f765ec2ce295c4 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Mon, 16 Feb 2026 12:37:32 +0500 Subject: [PATCH 52/65] Update simple_vector.cpp --- 05_week/tasks/simple_vector/simple_vector.cpp | 53 ++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/05_week/tasks/simple_vector/simple_vector.cpp b/05_week/tasks/simple_vector/simple_vector.cpp index 9b2ea971..8757efb0 100644 --- a/05_week/tasks/simple_vector/simple_vector.cpp +++ b/05_week/tasks/simple_vector/simple_vector.cpp @@ -1,5 +1,56 @@ +Вектор чисел +Необходимо реализовать класс SimpleVector, представляющий упрощенную реализацию контейнера std::vector для целочисленных элементов типа int в динамической памяти. +Класс предоставляет следующий функционал: + +Конструктор по умолчанию +Конструктор, принимающий размер вектора и заполняющий его нулями +Конструктор, принимающий список инициализации std::initializer_list, что позволит писать SimpleVector v = {1, 3, 5} +Конструктор копирования +Конструктор перемещения +Операторы присваивания копированием +Оператор присваивания перемещением +Деструктор +Метод Swap - принимает другой вектор и меняет содержимое текущего вектора с ним местами +Операторы индексирования []- позволяет изменять содержимое для неконстантного вектора +Метод Size - возвращает число элементов в векторе +Метод Capacity - возвращает текущее число выделенных ячеек памяти под вектор. +Метод Empty - возвращает true, если вектор пуст +Метод Data - прямой доступ к памяти, не позволяющий вносить изменения +Метод PushBack который вставляет элемент в конец вектора. +Метод PopBack - удаляет последний элемент вектора. При этом изменяется только размер, выделенную память изменять не нужно. +Метод Insert - принимает позицию (или const int*) и элемент, вставляет элемент перед указанной позицией, возвращает указатель на вставленный элемент, позволяющий вносить изменения. При вставке элементы контейнера, начиная с указанной позиции до конца вектора смещаются на одну позицию. Если передана некорректная позиция, вставка не происходит, возвращается указатель за последний элемент контейнера. +Метод Erase - принимает позицию (или const int*), удаляет элемент в указанной позиции и возвращает указатель на элемент, который был следующим за удаляемым. Элементы после указанной позиции сдвигаются. Если передана некорректная позиция, удаление не производится. +Метод Clear - очистить вектор. При этом, как правило, изменяется только размер, память очищать не нужно и выполнять релокации тоже. +Метод Resize - принимает размер и значение (по умолчанию 0), изменяет размер массива на заданный. Если переданный размер совпадает с текущим, то без изменений. Если меньше, то изменяет размер. Если больше, то при необходимости производит релокацию и заполняет элементы заданным значением +Метод Reserve - принимает новое значение вместимости, позволяя зарезервировать место в векторе. Если текущий Capacity не меньше переданного, то метод не должен ничего делать. В противном случае выполните релокацию в массив размера заданной вместимости. +Поддержка работы range-based for для контейнера. В данном случае для простоты допустимо возвращать указатели на первый элемент и за последний, концепция итераторов будет обсуждаться позже. +Операторы сравнения на равенство и неравенство, учитывающие размер и поэлементное сравнение элементов +При добавлении элемента, если память, выделенная для вектора, заполнена, то выполните релокацию: выделите массив вдвое большего размера, скопируйте элементы туда, после чего удалите старый массив. В этом случае вместимость должна увеличиться вдвое. Для вектора, сконструированного с помощью конструктора по умолчанию, вместимость == 0, при добавлении элемента вместимость становится 1. + +Примечание +Запрещено использовать стандартные контейнеры (std::vector, умные указатели) +Устройство вектора обсуждалось в конце третьей лекции +Для поддержки range-based for необходимы методы begin, end или внешние функции begin, end, принимающие заданную коллекцию, поэтому допустимо, чтобы они не соответствовали стайлгайду. Если стайлгайд не хочется +Для совместимости с алгоритмами стандартной библиотеки STL может потребоваться swap, ситуация аналогичная, но поскольку требуется внутри класса Swap, достаточно реализовать внешнюю функцию, вызывающую метод Swap контейнера class SimpleVector { -}; \ No newline at end of file +private: + int* data_; // начало данных + size_t size_; // размер + size_t capacity_; // емкость != размер. +public: + // Конструктор по умолчанию + SimpleVector() : data_(nullptr), size_(0), capacity_(0) {} // указатель на nullptr, размер = 0б емкость = 0ж + + // Конструктор, принимающий размер вектора и заполняющий его нулями + SimpleVector(size_t size) + + // Конструктор, принимающий размер и заполняющий нулями + explicit SimpleVector(size_t size) : data_(new size_t[size]), size_(size), capacity_(size) { + size_t i == 0; + for(size_t i == 0, size < i, i++) data_[i] = 0; + } + +}; From 79eaf59884f6de756ccaffcdcdb5ff8cccca2270 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Mon, 16 Feb 2026 15:39:14 +0500 Subject: [PATCH 53/65] Update cow_string.cpp --- 05_week/tasks/cow_string/cow_string.cpp | 166 ++++++++++++++++++++++++ 1 file changed, 166 insertions(+) diff --git a/05_week/tasks/cow_string/cow_string.cpp b/05_week/tasks/cow_string/cow_string.cpp index 34d59738..01756a5a 100644 --- a/05_week/tasks/cow_string/cow_string.cpp +++ b/05_week/tasks/cow_string/cow_string.cpp @@ -1,6 +1,172 @@ +/* + Коровья строка +Существуют разные подходы к управлению данными при копировании. Можно выделить следующие семантики: + +value-семантика - при копировании объекта происходит глубокое копирование (deep copy), все значения полностью объекта полностью копируются (реализовано в большинстве классов стандартной библиотеки C++). +reference-семантика - при копировании объекта его содержимое не копируется, а разделяется между копиями посредством ссылки или указателя. Также существует подход, который называют поверхностное копирование (shallow copy), когда происходит копирование только верхнего уровня оригинального объекта, а ссылки на внутренние части объекта остаются общими (реализовано по умолчанию в некоторых других языках). +cow-семантика (copy-on-write) - при копировании объекта создается shallow copy, что позволяет использовать объект на чтение без дополнительных затрат ресурсов, но при изменении объекта создается настоящая глубокая копия и изменения вносятся уже в копию. Таким образом, копирование совершается только при внесении изменений, что в определенных сценариях использования объекта позволяет увеличить производительность и уменьшить затраты на ресурсы. +Cow-семантика применяется в реализации строк Яндекса и фреймворка Qt. + +Необходимо реализовать класс CowString, который представляет собой упрощенную реализацию строки с copy-on-write семантикой. + +Класс предоставляет следующий функционал: + +Конструктор по умолчанию — создает пустую строку +Конструктор от const char* +Конструктор от std::string +Конструктор копирования — увеличивает счетчик ссылок, не копирует данные +Оператор присваивания копированием — увеличивает счетчик ссылок, не копирует данные +Конструктор перемещения +Оператор присваивания перемещением +Деструктор +Методы НЕ вызывающие копирования: + +Метод Size - возвращает длину строки без учета терминирующего нуля \0 +Метод ToCstr - возвращает указатель на данные +Метод ToString - возвращает std::string +Оператор [] - доступ к символу для чтения +Оператор неявного преобразования к C-строке +Методы, обеспечивающие модификацию на собственной копии данных: + +Оператор [] - доступ к символу для записи +Метод Append - добавляет строку из C-строки или std::string +Метод Substr - принимает позицию и количество символов (по умолчанию от начала до конца строки), возвращает соответствующую подстроку. Если позиция начала превышает длину, то возвращаем пустую строку. +Метод Clear - очистка строки +Для реализации строки удобно вынести все необходимые поля в отдельную структуру и кроме этого хранить в ней счетчик ссылок ref_count. + +Правильно поддерживая ref_count всегда будет известно, когда нужно удалять данные строки или когда нужно превращать shallow-copy в deep-copy. + +Примечание +Запрещено использовать std::string в реализации и умные указатели +Рекомендуется определять методы вне класса +При необходимости вспомогательные методы реализуются в закрытой части класса +Тесты оператор [] не проверяют на индекс вне диапазона +Проблемы реализации +В предполагаемой реализации имеется следующая проблема: при использовании модифицирующей версии оператора [] пользователь может сохранить ссылку и модифицировать символ позже, что нарушит cow-семантику. Для упрощения решать её не требуется. В Qt используют QCharRef для решения этой проблемы. +*/ + #include #include class CowString { +private: + char* data_; // указатель на данные + size_t size_; // размер + size_t capacity_; // емкость + size_t* ref_count_; // количество копий. + + // Универсальный конструктор. + void createNewCowString(const char* data, size_t len) { + if ((data == nullptr) || (len == 0)) capacity_ = 1; + else capacity_ = len + 1; + + ref_count_ = new int(1); + size_ = len; + data_ = new char[capacity_]; + ref_count_ = new size_(capacity_); + if ((data == nullptr) || (len == 0)) data_[0] = 0; // не указано что писать в пустую строку. + else for(size_t i = 0, i < len, i++) data_[i] = data[i]; +} + +public: + static const size_t npos = static_cast(-1); + + // Конструктор по умолчанию — создает пустую строку + CowString() createNewCowString(nullptr, 0); + + // Конструктор от const char* + CowString(const char* data, size_t len) createNewCowString(data, len); + + // Конструктор от std::string + CowString(const std::string& str) createNewCowString(str.c_str(), str.length()); + + // Конструктор копирования — увеличивает счетчик ссылок, не копирует данные + CowString(const CowString& obj) : data_(obj.data_), size_(obj.size_), capacity_(obj.capacity_), ref_count_(obj.ref_count_) { + ++(*ref_count_); + } + + // Оператор присваивания копированием — увеличивает счетчик ссылок, не копирует данные + CowString& operator=(const CowString& obj) { + if (this == &obj) return *this; // присвоение самому себе. + + data_ = obj.data_; + size_ = other.size_; + capacity_ = other.capacity_; + ref_count_ = other.ref_count_; + + if (ref_count_) { + ++(*ref_count_); + } + + } + + + // Конструктор перемещения + CowString(CowString&& obj) noexcept : data_(obj.data_), size_(obj.size_), capacity_(obj.capacity_), ref_count_(obj.ref_count_) { + // новую создали при заполнении полей, сейчас надо "освободить" перемещенную. + obj.data_ = new char[1]; + obj.size_ = 0; + obj.capacity_ = 1; + obj.data_[0] = '\0'; + obj.ref_count_ = new int(1); + } + + // Оператор присваивания перемещением + CowString& operator=(CowString&& obj) noexcept { + if (this == &obj) return *this; + + // копируем + data_ = obj.data_; + size_ = obj.size_; + capacity_ = obj.capacity_; + ref_count_ = obj.ref_count_; + + // очистка + obj.capacity_ = 1; + obj.data_ = new char[capacity_]; + obj.size_ = capacity_ - 1; + obj.data_[size_] = '\0'; + obj.ref_count_ = new size_t i(1); + } + + // Деструктор + ~CowString() { + if (ref_count_) { + --(*ref_count_); + if (*ref_count_ == 0) { + delete[] data_; + delete ref_count_; + data_ = nullptr; + size_ = 0; + capacity_ = 0; + ref_count_ = nullptr; + } + } + } + +// Методы НЕ вызывающие копирования: + + + + + +Оператор неявного преобразования к C-строке +Методы, обеспечивающие модификацию на собственной копии данных: + // Метод Size - возвращает длину строки без учета терминирующего нуля \0 + size_t Size() const return size_; + + // Метод ToCstr - возвращает указатель на данные + const char* ToCstr() const return data_; + + // Метод ToString - возвращает std::string + std::string ToString() const return std::string(data_, size_); + + // Оператор [] - доступ к символу для чтения + const char& operator[](size_t index) const return data_[index]; + + // Оператор неявного преобразования к C-строке + operator const char*() const return data_; + + // Методы, обеспечивающие модификацию на собственной копии данных: }; From fcb00cf1a175476929c076be11817344f866a9ae Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Mon, 16 Feb 2026 15:41:08 +0500 Subject: [PATCH 54/65] Update cow_string.cpp --- 05_week/tasks/cow_string/cow_string.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/05_week/tasks/cow_string/cow_string.cpp b/05_week/tasks/cow_string/cow_string.cpp index 01756a5a..66266ea2 100644 --- a/05_week/tasks/cow_string/cow_string.cpp +++ b/05_week/tasks/cow_string/cow_string.cpp @@ -72,13 +72,13 @@ class CowString { static const size_t npos = static_cast(-1); // Конструктор по умолчанию — создает пустую строку - CowString() createNewCowString(nullptr, 0); + CowString() {createNewCowString(nullptr, 0);} // Конструктор от const char* - CowString(const char* data, size_t len) createNewCowString(data, len); + CowString(const char* data, size_t len) {createNewCowString(data, len);} // Конструктор от std::string - CowString(const std::string& str) createNewCowString(str.c_str(), str.length()); + CowString(const std::string& str) {createNewCowString(str.c_str(), str.length());} // Конструктор копирования — увеличивает счетчик ссылок, не копирует данные CowString(const CowString& obj) : data_(obj.data_), size_(obj.size_), capacity_(obj.capacity_), ref_count_(obj.ref_count_) { From 6a9e8767162645b63383a458460e7b20a368056f Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Mon, 16 Feb 2026 15:42:48 +0500 Subject: [PATCH 55/65] Update cow_string.cpp --- 05_week/tasks/cow_string/cow_string.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/05_week/tasks/cow_string/cow_string.cpp b/05_week/tasks/cow_string/cow_string.cpp index 66266ea2..1624958e 100644 --- a/05_week/tasks/cow_string/cow_string.cpp +++ b/05_week/tasks/cow_string/cow_string.cpp @@ -70,9 +70,11 @@ class CowString { public: static const size_t npos = static_cast(-1); - + // Конструктор по умолчанию — создает пустую строку - CowString() {createNewCowString(nullptr, 0);} + CowString() { + createNewCowString(nullptr, 0); + } // Конструктор от const char* CowString(const char* data, size_t len) {createNewCowString(data, len);} From 77045c6e9e339cf17a3aebc83c5febefa3c670b1 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Mon, 16 Feb 2026 15:53:06 +0500 Subject: [PATCH 56/65] Update cow_string.cpp --- 05_week/tasks/cow_string/cow_string.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/05_week/tasks/cow_string/cow_string.cpp b/05_week/tasks/cow_string/cow_string.cpp index 1624958e..1728224b 100644 --- a/05_week/tasks/cow_string/cow_string.cpp +++ b/05_week/tasks/cow_string/cow_string.cpp @@ -65,7 +65,7 @@ class CowString { data_ = new char[capacity_]; ref_count_ = new size_(capacity_); if ((data == nullptr) || (len == 0)) data_[0] = 0; // не указано что писать в пустую строку. - else for(size_t i = 0, i < len, i++) data_[i] = data[i]; + else for(size_t i = 0; i < len; i++) data_[i] = data[i]; } public: @@ -128,7 +128,7 @@ class CowString { obj.data_ = new char[capacity_]; obj.size_ = capacity_ - 1; obj.data_[size_] = '\0'; - obj.ref_count_ = new size_t i(1); + obj.ref_count_ = new size_t(1); } // Деструктор From e3a905225baf3050c2e6a285c70dd0c5dc85405e Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Mon, 16 Feb 2026 16:25:21 +0500 Subject: [PATCH 57/65] Update cow_string.cpp --- 05_week/tasks/cow_string/cow_string.cpp | 101 ++++++++++++++++++++---- 1 file changed, 87 insertions(+), 14 deletions(-) diff --git a/05_week/tasks/cow_string/cow_string.cpp b/05_week/tasks/cow_string/cow_string.cpp index 1728224b..31ef3b56 100644 --- a/05_week/tasks/cow_string/cow_string.cpp +++ b/05_week/tasks/cow_string/cow_string.cpp @@ -60,10 +60,10 @@ class CowString { if ((data == nullptr) || (len == 0)) capacity_ = 1; else capacity_ = len + 1; - ref_count_ = new int(1); + ref_count_ = new size_t(1); size_ = len; data_ = new char[capacity_]; - ref_count_ = new size_(capacity_); + ref_count_ = new size_t(capacity_); if ((data == nullptr) || (len == 0)) data_[0] = 0; // не указано что писать в пустую строку. else for(size_t i = 0; i < len; i++) data_[i] = data[i]; } @@ -92,9 +92,9 @@ class CowString { if (this == &obj) return *this; // присвоение самому себе. data_ = obj.data_; - size_ = other.size_; - capacity_ = other.capacity_; - ref_count_ = other.ref_count_; + size_ = obj.size_; + capacity_ = obj.capacity_; + ref_count_ = obj.ref_count_; if (ref_count_) { ++(*ref_count_); @@ -110,7 +110,7 @@ class CowString { obj.size_ = 0; obj.capacity_ = 1; obj.data_[0] = '\0'; - obj.ref_count_ = new int(1); + obj.ref_count_ = new size_t(1); } // Оператор присваивания перемещением @@ -152,23 +152,96 @@ class CowString { -Оператор неявного преобразования к C-строке -Методы, обеспечивающие модификацию на собственной копии данных: +//Оператор неявного преобразования к C-строке +// Оператор неявного преобразования к C-строке +// Методы, обеспечивающие модификацию на собственной копии данных: // Метод Size - возвращает длину строки без учета терминирующего нуля \0 - size_t Size() const return size_; + size_t Size() const {return size_;} // Метод ToCstr - возвращает указатель на данные - const char* ToCstr() const return data_; + const char* ToCstr() const {return data_;} // Метод ToString - возвращает std::string - std::string ToString() const return std::string(data_, size_); + std::string ToString() const {return std::string(data_, size_);} // Оператор [] - доступ к символу для чтения - const char& operator[](size_t index) const return data_[index]; + const char& operator[](size_t index) const {return data_[index];} // Оператор неявного преобразования к C-строке - operator const char*() const return data_; + operator const char*() const {return data_;} + +// Методы, обеспечивающие модификацию на собственной копии данных: + // Оператор [] - доступ к символу для записи + char& operator[](size_t index) {return data_[index];} + + // Метод Append - добавляет строку из C-строки или std::string + + CowString& Append(const char* str) { + if (str == nullptr || *str == '\0') return *this; + + size_t len = std::strlen(str); + if (len == 0) return *this; + + size_t new_size = size_ + len; + + if (new_size + 1 > capacity_) { + size_t new_capacity = new_size + 1; + char* new_data = new char[new_capacity]; + + for(size_t i = 0; i < (new_size - len); i++) new_data[i] = data_[i]; + for(size_t i = 0; i < len; i++) new_data[(new_size - len) +i] = str[i]; + + // Освобождаем старые данные + if (ref_count_ && *ref_count_ == 1) { + delete[] data_; + delete ref_count_; + } else { + --(*ref_count_); + } + + data_ = new_data; + size_ = new_size; + capacity_ = new_capacity; + ref_count_ = new size_t(1); + } else { + std::memcpy(data_ + size_, str, len); + size_ = new_size; + data_[new_size] = '\0'; + } + + return *this; + } + + // Метод Substr - принимает позицию и количество символов (по умолчанию от начала до конца строки), возвращает соответствующую подстроку. Если позиция начала превышает длину, то возвращаем пустую строку. + CowString Substr(size_t pos = 0, size_t count = npos) const { + if (pos >= size_) { + return CowString(); + } + + size_t start = pos; + size_t len = (count == npos || count > size_ - pos) ? size_ - pos : count; + + char* data = new char[len + 1]; + + for(size_t i = 0; i < len; i++) data[i] = data_[i] + start; + + CowString res(data); + delete[] data; + + return res; + } + + // Метод Clear - очистка строки + void Clear() { + if (size_ == 0) return; + + if (ref_count_ && *ref_count_ > 1) createNewCowString(nullptr, 0); + else { + size_ = 0; + data_[0] = '\0'; + } + } + - // Методы, обеспечивающие модификацию на собственной копии данных: }; From 56b7044e3931f3e60b1ae38496138e1eb1cbd749 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Mon, 16 Feb 2026 16:27:24 +0500 Subject: [PATCH 58/65] Update cow_string.cpp --- 05_week/tasks/cow_string/cow_string.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/05_week/tasks/cow_string/cow_string.cpp b/05_week/tasks/cow_string/cow_string.cpp index 31ef3b56..131745aa 100644 --- a/05_week/tasks/cow_string/cow_string.cpp +++ b/05_week/tasks/cow_string/cow_string.cpp @@ -176,7 +176,7 @@ class CowString { // Метод Append - добавляет строку из C-строки или std::string - CowString& Append(const char* str) { + CowString& Append(const char* str) { if (str == nullptr || *str == '\0') return *this; size_t len = std::strlen(str); @@ -212,6 +212,10 @@ class CowString { return *this; } + CowString& Append(const std::string& str) { + return Append(str.c_str()); + } + // Метод Substr - принимает позицию и количество символов (по умолчанию от начала до конца строки), возвращает соответствующую подстроку. Если позиция начала превышает длину, то возвращаем пустую строку. CowString Substr(size_t pos = 0, size_t count = npos) const { if (pos >= size_) { From 314641fc7f371e493d49cbcb448ef8a48f8e8721 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Mon, 16 Feb 2026 16:29:33 +0500 Subject: [PATCH 59/65] Update cow_string.cpp --- 05_week/tasks/cow_string/cow_string.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/05_week/tasks/cow_string/cow_string.cpp b/05_week/tasks/cow_string/cow_string.cpp index 131745aa..214ef8d0 100644 --- a/05_week/tasks/cow_string/cow_string.cpp +++ b/05_week/tasks/cow_string/cow_string.cpp @@ -246,6 +246,23 @@ class CowString { } } + size_t Find(const char* str, size_t pos = 0) const { + if (str == nullptr) return npos; + if (*str == '\0') return 0; + + if (pos >= size_) return npos; + + size_t len = std::strlen(str); + + if (len > size_ - pos) return npos; + + for (size_t i = pos; i <= size_ - len; ++i) { + if (std::memcmp(data_ + i, str, len) == 0) { + return i; + } + } + return npos; + } }; From b98782ae495888f829433858e8dfadd09ae732e8 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Mon, 16 Feb 2026 22:19:15 +0500 Subject: [PATCH 60/65] Update cow_string.cpp --- 05_week/tasks/cow_string/cow_string.cpp | 302 +++++++++++++----------- 1 file changed, 159 insertions(+), 143 deletions(-) diff --git a/05_week/tasks/cow_string/cow_string.cpp b/05_week/tasks/cow_string/cow_string.cpp index 214ef8d0..ea059e1a 100644 --- a/05_week/tasks/cow_string/cow_string.cpp +++ b/05_week/tasks/cow_string/cow_string.cpp @@ -44,225 +44,241 @@ Cow-семантика применяется в реализации строк Проблемы реализации В предполагаемой реализации имеется следующая проблема: при использовании модифицирующей версии оператора [] пользователь может сохранить ссылку и модифицировать символ позже, что нарушит cow-семантику. Для упрощения решать её не требуется. В Qt используют QCharRef для решения этой проблемы. */ - #include -#include +#include class CowString { private: - char* data_; // указатель на данные - size_t size_; // размер - size_t capacity_; // емкость - size_t* ref_count_; // количество копий. - - // Универсальный конструктор. - void createNewCowString(const char* data, size_t len) { - if ((data == nullptr) || (len == 0)) capacity_ = 1; - else capacity_ = len + 1; - - ref_count_ = new size_t(1); - size_ = len; - data_ = new char[capacity_]; - ref_count_ = new size_t(capacity_); - if ((data == nullptr) || (len == 0)) data_[0] = 0; // не указано что писать в пустую строку. - else for(size_t i = 0; i < len; i++) data_[i] = data[i]; -} + struct StringData { + char* data; // указатель на данные + size_t size; // размер + size_t capacity; // емкость + int ref_count; // // количество копий. int а не size_t т.к. проще отслеживать переход через 0 + + StringData(const char* buf, size_t len) : size(len), capacity(len + 1), ref_count(1) { + data = new char[capacity]; // выделение места для данных + for(size_t i = 0; i < len; i++) data[i] = buf[i]; // копирование данных + data[len] = '\0'; // последний символ + } + + + StringData(size_t cap) : size(0), capacity(cap), ref_count(1) { + data = new char[capacity]; + data[0] = '\0'; // обнуление нулевого он же последний элемент + } + + + // Диструктор + ~StringData() { delete[] data;} + + + void release_ref() { + if (--ref_count == 0) { + delete this; + } + } + }; + + StringData* str_data; + + void detach() { + if (str_data->ref_count > 1) { + StringData* new_data = new StringData(str_data->data, str_data->size); + str_data->release_ref(); + str_data = new_data; + } + } + + void ensure_unique() { + if (str_data->ref_count > 1) { + StringData* new_data = new StringData(str_data->data, str_data->size); + str_data->release_ref(); + str_data = new_data; + } + } public: - static const size_t npos = static_cast(-1); + inline static const size_t npos = -1; // Конструктор по умолчанию — создает пустую строку - CowString() { - createNewCowString(nullptr, 0); - } + CowString() : str_data(new StringData(1)) {} + // Конструктор от const char* - CowString(const char* data, size_t len) {createNewCowString(data, len);} + CowString(const char* str) { + size_t len = 1; // если nullptr то останится 1 + + if (str != nullptr) len = std::strlen(str); // не nullptr значит задаем длину + + str_data = new StringData(str, len); + } + // Конструктор от std::string - CowString(const std::string& str) {createNewCowString(str.c_str(), str.length());} + CowString(const std::string& str) : str_data(new StringData(str.c_str(), str.length())) {} // Конструктор копирования — увеличивает счетчик ссылок, не копирует данные - CowString(const CowString& obj) : data_(obj.data_), size_(obj.size_), capacity_(obj.capacity_), ref_count_(obj.ref_count_) { - ++(*ref_count_); + CowString(const CowString& other) : str_data(other.str_data) { + str_data->ref_count++; // } + // Оператор присваивания копированием — увеличивает счетчик ссылок, не копирует данные CowString& operator=(const CowString& obj) { - if (this == &obj) return *this; // присвоение самому себе. - - data_ = obj.data_; - size_ = obj.size_; - capacity_ = obj.capacity_; - ref_count_ = obj.ref_count_; - - if (ref_count_) { - ++(*ref_count_); - } - + if (this != &obj){ // есть, что копирвать. + str_data->release_ref() ; + str_data = obj.str_data; + str_data->ref_count++; + } + return *this; } // Конструктор перемещения - CowString(CowString&& obj) noexcept : data_(obj.data_), size_(obj.size_), capacity_(obj.capacity_), ref_count_(obj.ref_count_) { - // новую создали при заполнении полей, сейчас надо "освободить" перемещенную. - obj.data_ = new char[1]; - obj.size_ = 0; - obj.capacity_ = 1; - obj.data_[0] = '\0'; - obj.ref_count_ = new size_t(1); - } + CowString(CowString&& other) noexcept : str_data(other.str_data) { other.str_data = new StringData(1); } // новую структуру создали при заполнении полей, сейчас надо "освободить" перемещенную. + + // Оператор присваивания перемещением CowString& operator=(CowString&& obj) noexcept { - if (this == &obj) return *this; - - // копируем - data_ = obj.data_; - size_ = obj.size_; - capacity_ = obj.capacity_; - ref_count_ = obj.ref_count_; - - // очистка - obj.capacity_ = 1; - obj.data_ = new char[capacity_]; - obj.size_ = capacity_ - 1; - obj.data_[size_] = '\0'; - obj.ref_count_ = new size_t(1); - } - - // Деструктор - ~CowString() { - if (ref_count_) { - --(*ref_count_); - if (*ref_count_ == 0) { - delete[] data_; - delete ref_count_; - data_ = nullptr; - size_ = 0; - capacity_ = 0; - ref_count_ = nullptr; - } + if (this != &obj) { // перемещние обьекта, проверяем, что перемещаем не сами себя + str_data->release_ref(); + str_data = obj.str_data; + obj.str_data = new StringData(1); } - } + return *this; + } -// Методы НЕ вызывающие копирования: + // Деструктор + ~CowString() { str_data->release_ref();} -//Оператор неявного преобразования к C-строке + //Оператор неявного преобразования к C-строке // Оператор неявного преобразования к C-строке // Методы, обеспечивающие модификацию на собственной копии данных: // Метод Size - возвращает длину строки без учета терминирующего нуля \0 - size_t Size() const {return size_;} + size_t Size() const { return str_data->size; } // Метод ToCstr - возвращает указатель на данные - const char* ToCstr() const {return data_;} + const char* ToCstr() const { return str_data->data; } // Метод ToString - возвращает std::string - std::string ToString() const {return std::string(data_, size_);} + std::string ToString() const { return std::string(str_data->data, str_data->size); } // Оператор [] - доступ к символу для чтения - const char& operator[](size_t index) const {return data_[index];} + const char& operator[](size_t i) const { return str_data->data[i]; } // Оператор неявного преобразования к C-строке - operator const char*() const {return data_;} + operator const char*() const { return str_data->data; } + // Методы, обеспечивающие модификацию на собственной копии данных: // Оператор [] - доступ к символу для записи - char& operator[](size_t index) {return data_[index];} + char& operator[](size_t i) { + ensure_unique(); + return str_data->data[i]; + } - // Метод Append - добавляет строку из C-строки или std::string + // Метод Append - добавляет строку из C-строки + CowString& Append(const char* obj) { + if (obj == nullptr || *obj == '\0') return *this; // проверка на самого себя + + size_t len = std::strlen(obj); // длина + + if (len == 0) return *this; // защита - CowString& Append(const char* str) { - if (str == nullptr || *str == '\0') return *this; - - size_t len = std::strlen(str); - if (len == 0) return *this; + ensure_unique(); - size_t new_size = size_ + len; - - if (new_size + 1 > capacity_) { - size_t new_capacity = new_size + 1; - char* new_data = new char[new_capacity]; - - for(size_t i = 0; i < (new_size - len); i++) new_data[i] = data_[i]; - for(size_t i = 0; i < len; i++) new_data[(new_size - len) +i] = str[i]; - - // Освобождаем старые данные - if (ref_count_ && *ref_count_ == 1) { - delete[] data_; - delete ref_count_; - } else { - --(*ref_count_); - } + size_t new_size = str_data->size + len; // расчет новой емкости буфера + // возмоно емкостьисходного больше чем требуется для результирующей строки + if (new_size + 1 > str_data->capacity) {// добавляем строку + size_t new_capacity = new_size + 1; // + StringData* new_data = new StringData(new_capacity); // выделение памяти под увеличенную строку + // for(size_t i = 0; i < str_data->size; i++) new_data->data[i] = str_data->data[i]; + // for(size_t i = 0; i < len; i++) new_data->data[new_size - len + i] = obj->data[i]; + std::memcpy(new_data->data, str_data->data, str_data->size); // перемещение первойчасти + std::memcpy(new_data->data + str_data->size, obj, len); // перемещение второй части + new_data->data[new_size] = '\0'; + new_data->size = new_size; - data_ = new_data; - size_ = new_size; - capacity_ = new_capacity; - ref_count_ = new size_t(1); - } else { - std::memcpy(data_ + size_, str, len); - size_ = new_size; - data_[new_size] = '\0'; + str_data->release_ref(); + str_data = new_data; + } + else { + std::memcpy(str_data->data + str_data->size, obj, len); // перемещение + str_data->size = new_size; + str_data->data[new_size] = '\0'; } return *this; } - CowString& Append(const std::string& str) { - return Append(str.c_str()); - } + // Метод Append для std::string + CowString& Append(const std::string& str) { return Append(str.c_str()); } // Метод Substr - принимает позицию и количество символов (по умолчанию от начала до конца строки), возвращает соответствующую подстроку. Если позиция начала превышает длину, то возвращаем пустую строку. CowString Substr(size_t pos = 0, size_t count = npos) const { - if (pos >= size_) { - return CowString(); - } + if (pos >= str_data->size) return CowString(); // проверкаб что позиция не больше размера size_t start = pos; - size_t len = (count == npos || count > size_ - pos) ? size_ - pos : count; + size_t len = ((count == npos) || (count > str_data->size - pos)) ? str_data->size - pos : count; - char* data = new char[len + 1]; - - for(size_t i = 0; i < len; i++) data[i] = data_[i] + start; + char* buf = new char[len + 1]; // выделение места для данных + std::memcpy(buf, str_data->data + start, len); // копирование данных + buf[len] = '\0'; // последний символ - CowString res(data); - delete[] data; + CowString result(buf); // формируем даныне + delete[] buf; // освобождение памяти - return res; + return result; } - // Метод Clear - очистка строки + // Метод Clear void Clear() { - if (size_ == 0) return; - - if (ref_count_ && *ref_count_ > 1) createNewCowString(nullptr, 0); - else { - size_ = 0; - data_[0] = '\0'; + if (str_data->size == 0) return; // данных нет + + if (str_data->ref_count > 1) { // не первая копия. очищаем и удаляем + str_data->release_ref(); + str_data = new StringData(1); + } + else { // первый экземпляр, просто очистка размера и данных + str_data->size = 0; + str_data->data[0] = '\0'; } } + // Метод Empty + bool Empty() const { return str_data->size == 0; } // Сокращаем размер до 0 + + // Метод Find для символа + size_t Find(char symbl, size_t i = 0) const { + if (i >= str_data->size) return npos; // искомая позиция вне размера данных + + for (size_t j = i; j < str_data->size; ++j) + if (str_data->data[j] == symbl) return j; // Символ найден + + + return npos; // ничего не найдено + } + + // Метод Find для C-строки size_t Find(const char* str, size_t pos = 0) const { - if (str == nullptr) return npos; + if (str == nullptr) return npos; // пустой указатель - if (*str == '\0') return 0; + if (*str == '\0') return 0; // оказались в конце строки - if (pos >= size_) return npos; + if (pos >= str_data->size) return npos; // начало поиска больше размера size_t len = std::strlen(str); - - if (len > size_ - pos) return npos; + + if (len > str_data->size - pos) return npos; - for (size_t i = pos; i <= size_ - len; ++i) { - if (std::memcmp(data_ + i, str, len) == 0) { - return i; - } + for (size_t i = pos; i <= str_data->size - len; ++i) { + if (std::memcmp(str_data->data + i, str, len) == 0) return i; // послеовательность обнаружен } return npos; } - }; From 83dc5fa3ca576bab4840751121c377cbe26771d5 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Mon, 16 Feb 2026 23:51:42 +0500 Subject: [PATCH 61/65] Update simple_vector.cpp --- 05_week/tasks/simple_vector/simple_vector.cpp | 237 +++++++++++++++++- 1 file changed, 226 insertions(+), 11 deletions(-) diff --git a/05_week/tasks/simple_vector/simple_vector.cpp b/05_week/tasks/simple_vector/simple_vector.cpp index 8757efb0..6dd908c5 100644 --- a/05_week/tasks/simple_vector/simple_vector.cpp +++ b/05_week/tasks/simple_vector/simple_vector.cpp @@ -1,4 +1,4 @@ -Вектор чисел +/*ектор чисел Необходимо реализовать класс SimpleVector, представляющий упрощенную реализацию контейнера std::vector для целочисленных элементов типа int в динамической памяти. Класс предоставляет следующий функционал: @@ -33,24 +33,239 @@ Устройство вектора обсуждалось в конце третьей лекции Для поддержки range-based for необходимы методы begin, end или внешние функции begin, end, принимающие заданную коллекцию, поэтому допустимо, чтобы они не соответствовали стайлгайду. Если стайлгайд не хочется Для совместимости с алгоритмами стандартной библиотеки STL может потребоваться swap, ситуация аналогичная, но поскольку требуется внутри класса Swap, достаточно реализовать внешнюю функцию, вызывающую метод Swap контейнера +*/ -class SimpleVector { +// simple_vector.cpp +#include +#include +#include // для memcpy +class SimpleVector { private: - int* data_; // начало данных - size_t size_; // размер - size_t capacity_; // емкость != размер. + int* data_; + size_t size_; + size_t capacity_; + public: // Конструктор по умолчанию - SimpleVector() : data_(nullptr), size_(0), capacity_(0) {} // указатель на nullptr, размер = 0б емкость = 0ж + SimpleVector() : data_(nullptr), size_(0), capacity_(0) {} // пустой указатель // Конструктор, принимающий размер вектора и заполняющий его нулями - SimpleVector(size_t size) + explicit SimpleVector(size_t size) : data_(new int[size]), size_(size), capacity_(size) { + for (size_t i = 0; i < size_; ++i) data_[i] = 0;// заполнение нулями. + } + + // Конструктор, принимающий размер и значение для заполнения + SimpleVector(size_t size, int data) : data_(new int[size]), size_(size), capacity_(size) { + for (size_t i = 0; i < size_; ++i) data_[i] = data;// заполнение нулями. + } + + // ККонструктор, принимающий список инициализации std::initializer_list, что позволит писать SimpleVector v = {1, 3, 5} + SimpleVector(std::initializer_list init) : data_(new int[init.size()]), size_(init.size()), capacity_(init.size()) { + std::copy(init.begin(), init.end(), data_); // + } + + // Конструктор копирования + SimpleVector(const SimpleVector& obj){ + + if(obj.capacity_ == 0) data_ = nullptr; // проверка, если емкость 0, то nullptr + else data_ = new int[obj.capacity_]; // иначе выделяем место для объекта + + // переписывание данных + size_ = obj.size_; + + capacity_ = obj.capacity_; + + std::copy(obj.data_, obj.data_ + obj.size_, data_); + } + + // Конструктор перемещения + SimpleVector(SimpleVector&& obj) noexcept : data_(obj.data_), size_(obj.size_), capacity_(obj.capacity_) { + // скопировали в списке инициализации, теперь обнуляем исходник + obj.data_ = nullptr; + obj.size_ = 0; + obj.capacity_ = 0; + } + + // Оператор присваивания копированием + SimpleVector& operator=(const SimpleVector& obj) { + if (this != &obj) { // проверка на самого себя + SimpleVector temp(obj); + Swap(temp); + } + return *this; + } + + // Оператор присваивания перемещением + SimpleVector& operator=(SimpleVector&& obj) noexcept { + if (this != &obj) { // проверка на самого себя + delete[] data_; // очистка + data_ = obj.data_; //присвоение + size_ = obj.size_; + capacity_ = obj.capacity_; + + // обнуляем исходник + obj.data_ = nullptr; + obj.size_ = 0; + obj.capacity_ = 0; + } + return *this; + } + + // Деструктор + ~SimpleVector() { delete[] data_; } + + // Метод Swap - принимает другой вектор и меняет содержимое текущего вектора с ним местами + void Swap(SimpleVector& obj) noexcept { + + size_t temp = obj.size_; // переменная для временного хранения size_ и capacity_ + + obj.size_ = size_; + size_ = temp; + + temp = obj.capacity_; + obj.capacity_ = capacity_; + capacity_ = temp; + + int* tempDdata; // переменная для временного хранения data_ + + tempDdata = obj.data_; + obj.data_ = data_; + data_ = tempDdata; + } + + // Операторы индексирования []- позволяет изменять содержимое для неконстантного вектора + int& operator[](size_t i) { + return data_[i]; + } + + const int& operator[](size_t i) const { + return data_[i]; + } + // Метод Size - возвращает число элементов в векторе + size_t Size() const { return size_; } - // Конструктор, принимающий размер и заполняющий нулями - explicit SimpleVector(size_t size) : data_(new size_t[size]), size_(size), capacity_(size) { - size_t i == 0; - for(size_t i == 0, size < i, i++) data_[i] = 0; + // Метод Capacity - возвращает текущее число выделенных ячеек памяти под вектор. + size_t Capacity() const { return capacity_; } + + // Метод Empty - возвращает true, если вектор пуст + bool Empty() const { return size_ == 0; } + + // Метод Data - прямой доступ к памяти, не позволяющий вносить изменения + const int* Data() const { return data_; } + + // Метод PushBack который вставляет элемент в конец вектора. + void PushBack(int value) { + // места может не быть, сначала проверка, есть ли место, .если нет увеличиваем емкость на единицу. + if (size_ == capacity_) { + size_t new_capacity = capacity_ * 2;// т.к. есть требование "В этом случае вместимость должна увеличиться вдвое" + if(new_capacity == 0) new_capacity = 1; + Reserve(new_capacity); + } + data_[size_++] = value; + } + + // Метод PopBack - удаляет последний элемент вектора. При этом изменяется только размер, выделенную память изменять не нужно. + void PopBack() { if (size_ > 0) --size_; } + + // Метод Insert - принимает позицию (или const int*) и элемент, вставляет элемент перед указанной позицией, возвращает указатель на вставленный элемент, позволяющий вносить изменения. При вставке элементы контейнера, начиная с указанной позиции до конца вектора смещаются на одну позицию. Если передана некорректная позиция, вставка не происходит, возвращается указатель за последний элемент контейнера. + int* Insert(const int* pos, int data) { + if ((pos < data_) || (pos > data_ + size_)) return data_ + size_; // проверка, что указатель указатель места вклейки валиден + + size_t i = pos - data_; // расчет индекса начала сдвига + + // возможно Размер совпал с емкостью, + if (size_ == capacity_) { // Тогда надо увеличить емкость на 1 + size_t new_capacity = capacity_ + 1; + Reserve(new_capacity); + } + + // Сдвигаем с элементы после места вклейки вправо + for (size_t j = size_; j > i; --j) data_[j] = data_[j - 1]; + + data_[i] = data; // вклеиваем элемент + ++size_; // помним про то, что надо увеличить размер + + return data_ + i; + } + +// Метод Erase - принимает позицию (или const int*), удаляет элемент в указанной позиции и возвращает указатель на элемент, который был следующим за удаляемым. Элементы после указанной позиции сдвигаются. Если передана некорректная позиция, удаление не производится. + + int* Erase(const int* pos) { + if (pos < data_ || pos >= data_ + size_) return data_ + size_; // проверка, что указатель указатель места вклейки валиден + + size_t i = pos - data_; // расчет индекса начала сдвига + + // Сдвигаем элементы + for (size_t j = i; j < size_ - 1; ++j) data_[j] = data_[j + 1]; + + --size_; // помним про то, что надо увеличить размер + + return data_ + i; + } + + // Метод Clear - очистить вектор. При этом, как правило, изменяется только размер, память очищать не нужно и выполнять релокации тоже. + void Clear() { size_ = 0; } + + // Метод Reserve - принимает новое значение вместимости, позволяя зарезервировать место в векторе. Если текущий Capacity не меньше переданного, то метод не должен ничего делать. В противном случае выполните релокацию в массив размера заданной вместимости. + void Resize(size_t newSize, int data = 0) { + if (newSize == size_) return; // метод не должен ничего делать. + + if (newSize < size_) size_ = newSize; + else { + if (newSize > capacity_) { + Reserve(newSize); + } + + // Заполняем элементы значением data + for (size_t i = size_; i < newSize; ++i) { + data_[i] = data; + } + size_ = newSize; + } + } + + // Метод Reserve + void Reserve(size_t new_capacity) { + if (new_capacity <= capacity_) return; // метод не должен ничего делать. + + int* new_data = new int[new_capacity]; + if (data_) { + std::copy(data_, data_ + size_, new_data); + delete[] data_; + } + data_ = new_data; + capacity_ = new_capacity; } + // Поддержка работы range-based for для контейнера. В данном случае для простоты допустимо возвращать указатели на первый элемент и за последний, концепция итераторов будет обсуждаться позже. + int* begin() { return data_; } + + const int* begin() const { return data_; } + + int* end() { return data_ + size_; } + + const int* end() const { return data_ + size_; } + + // Операторы сравнения на равенство и неравенство, учитывающие размер и поэлементное сравнение элементов + bool operator==(const SimpleVector& obj) const { + if (size_ != obj.size_) { + return false; + } + for (size_t i = 0; i < size_; ++i) { + if (data_[i] != obj.data_[i]) { + return false; + } + } + return true; + } + + bool operator!=(const SimpleVector& obj) const { + return !(*this == obj); + } }; + +// Для совместимости с алгоритмами стандартной библиотеки STL может потребоваться swap, ситуация аналогичная, но поскольку требуется внутри класса Swap, достаточно реализовать внешнюю функцию, вызывающую метод Swap контейнера +void swap(SimpleVector& lhs, SimpleVector& rhs) noexcept { + lhs.Swap(rhs); +} From a8f3e4dc8b2258ae02ba7c2b87585ec4c4aac4ff Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Sun, 22 Feb 2026 23:42:48 +0500 Subject: [PATCH 62/65] Update unique_ptr.cpp --- 06_week/tasks/unique_ptr/unique_ptr.cpp | 117 +++++++++++++++++++++++- 1 file changed, 115 insertions(+), 2 deletions(-) diff --git a/06_week/tasks/unique_ptr/unique_ptr.cpp b/06_week/tasks/unique_ptr/unique_ptr.cpp index db8729ad..ffa94622 100644 --- a/06_week/tasks/unique_ptr/unique_ptr.cpp +++ b/06_week/tasks/unique_ptr/unique_ptr.cpp @@ -1,6 +1,119 @@ #include -class UniquePtr { +/*Умный указатель уникального владения + +Необходимо реализовать класс UniquePtr, который реализует семантику уникального владения строкой std::string. Класс соответствует умному указателю std::unique_ptr. + +Класс предоставляет следующий функционал: + + Все необходимые конструкторы умного указателя с уникальным владением + Операторы, реализующие поведение указателей + Метод Get - получить сырой указатель + Метод Release - освобождает владение (возвращает указатель и становится nullptr) + Метод Reset - удаляет старый объект и принимает владение новым + Метод Swap - обменивается владеющими указателями с другим UniquePtr + Оператор bool() - приводит указатель к типу bool + +Необходимо реализовать: + + Функию MakeUnique - принимает строку и возвращает умный указатель UniquePtr. Функция должна поддерживать как копирование, так и перемещение принимаемого объекта + Функцию Swap - для обмена умными указателями UniquePtr + +Примечание + + Запрещено использовать умные указатели STL в реализации +*/ + + + +class UniquePtr{ +private: + std::string* ptr_; + +public: + // Все необходимые конструкторы умного указателя с уникальным владением + UniquePtr(): ptr_(nullptr) {} + UniquePtr(std::string* ptr) : ptr_(ptr){} + UniquePtr(UniquePtr&& ptrA) noexcept : ptr_(ptrA.ptr_) { ptrA.ptr_ = nullptr;} + + + // Оператор перемещения + UniquePtr& operator=(UniquePtr&& ptrA) noexcept { + if (this != &ptrA) { + delete ptr_; + ptr_ = ptrA.ptr_; + ptrA.ptr_ = nullptr; + } + return *this; + } + + // Деструктор + ~UniquePtr() { delete ptr_; } + + std::string& operator*() const { return *ptr_; } + std::string* operator->() const { return ptr_; } + + // Получить сырой указатель + std::string* Get() const { return ptr_; } + + + // Метод Release - освобождает владение (возвращает указатель и становится nullptr) + std::string* Release() { + std::string* temp; + temp = ptr_; + ptr_ = nullptr; + return temp; + } + + + // Метод Reset - удаляет старый объект и принимает владение новым + void Reset(std::string* ptr = nullptr) { + delete ptr_; + ptr_ = ptr; + } + + + /* + // Метод Swap - обменивается владеющими указателями с другим UniquePtr + void Swap(UniquePtr& ptrA) noexcept { + std::string* temp = ptrA.ptr_; + ptrA.ptr_ = this->ptr_; + this->ptr_ = temp; + } + */ + // Обменяться указателями (без использования библиотечных функций) + void Swap(UniquePtr& other) noexcept { + std::string* temp = this->ptr_; + this->ptr_ = other.ptr_; + other.ptr_ = temp; + } + + // Оператор bool() - приводит указатель к типу bool + explicit operator bool() const { return ptr_ != nullptr;} + + + // Запрет копирования + UniquePtr(const UniquePtr&) = delete; + UniquePtr& operator=(const UniquePtr&) = delete; + +}; + + +//Необходимо реализовать: + +// Функию MakeUnique - принимает строку и возвращает умный указатель UniquePtr. Функция должна поддерживать как копирование, так и перемещение принимаемого объекта + +UniquePtr MakeUnique(const std::string& data); +UniquePtr MakeUnique(std::string&& data); + +UniquePtr MakeUnique(const std::string& data) { return UniquePtr(new std::string(data)); } + +UniquePtr MakeUnique(std::string&& data) { return UniquePtr(new std::string(std::move(data))); } + + +// Функцию Swap - для обмена умными указателями UniquePtr +void Swap(UniquePtr& dataA, UniquePtr& dataB) noexcept; + +void Swap(UniquePtr& dataA, UniquePtr& dataB) noexcept {dataA.Swap(dataB); } -}; \ No newline at end of file From 50e81e133a895ae9627be22a931d94bf5b56cbd0 Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Mon, 23 Feb 2026 21:28:27 +0500 Subject: [PATCH 63/65] Update smart_ptr.cpp --- 06_week/tasks/smart_ptr/smart_ptr.cpp | 366 +++++++++++++++++++++++++- 1 file changed, 365 insertions(+), 1 deletion(-) diff --git a/06_week/tasks/smart_ptr/smart_ptr.cpp b/06_week/tasks/smart_ptr/smart_ptr.cpp index 05de4dc8..98345916 100644 --- a/06_week/tasks/smart_ptr/smart_ptr.cpp +++ b/06_week/tasks/smart_ptr/smart_ptr.cpp @@ -1,10 +1,374 @@ + +/* +Умные указатели + +Необходимо реализовать классы SharedPtr и WeakPtr, которые представляют собой аналоги std::shared_ptr и std::weak_ptr. То есть SharedPtr реализует семантику разделяемого владения, а WeakPtr представляет наблюдателя. В качестве объекта владения выступает строка std::string. + +Класс SharedPtr предоставляет следующий функционал: + + Все необходимые конструкторы умного указателя с уникальным владением + Операторы, реализующие поведение указателей + Метод Get - получить сырой указатель + Метод Reset - удаляет старый объект и принимает владение новым + Метод Swap - обменивается владеющими указателями с другим SharedPtr + Метод UseCount - возвращает количество владельцев + Оператор bool() - приводит указатель к типу bool + +Класс WeakPtr предоставляет следующий функционал: + + Все необходимые конструкторы умного указателя с уникальным владением + Операторы, реализующие поведение указателей + Метод Reset - убирает ссылку на владеющий объект + Метод Swap - обменивается владеющими указателями с другим WeakPtr + Метод UseCount - возвращает количество владельцев + Метод Expired - проверяет, истекло ли время жизни исходного объекта + Метод Lock - создает владеющий указатель SharedPtr на объект, если он ещё жив + +Необходимо реализовать: + + Функию MakeShared - принимает строку и возвращает умный указатель SharedPtr. Функция должна поддерживать как копирование, так и перемещение принимаемого объекта. + Функцию Swap - для обмена умными указателями SharedPtr, и указателями WeakPtr + +Примечание + + Запрещено использовать умные указатели STL в реализации + Одна из задач, где может пригодиться ключевое слово friend, но желательно им не злоупотреблять + Счетчики допустимо использовать обычные, не атомарные + Метод UseCount класса WeakPtr возвращает именно владельцев, поскольку именно владение определяет время жизни объекта + + +*/ + + #include +// Forward declarations +class SharedPtr; +class WeakPtr; class SharedPtr { +private: + std::string* ptr_; // Указатель + size_t* sharedPtrCount_; // Счетчик сильных ссылок + size_t* weakPtrCount_; // Счетчик слабых ссылок + + + +public: + // Все необходимые конструкторы умного указателя с уникальным владением + SharedPtr() : ptr_(nullptr), sharedPtrCount_(nullptr), weakPtrCount_(nullptr) {} + explicit SharedPtr(std::string* p) : ptr_(p) { + if (p != nullptr) { + sharedPtrCount_ = new size_t(1); + weakPtrCount_ = new size_t(0); + } else { + sharedPtrCount_ = nullptr; + weakPtrCount_ = nullptr; + } + } + + SharedPtr(const SharedPtr& data) : ptr_(data.ptr_), sharedPtrCount_(data.sharedPtrCount_), weakPtrCount_(data.weakPtrCount_) { + if (sharedPtrCount_ != nullptr) (*sharedPtrCount_)++; + } + + SharedPtr(SharedPtr&& data) noexcept : ptr_(data.ptr_), sharedPtrCount_(data.sharedPtrCount_), weakPtrCount_(data.weakPtrCount_) { + data.ptr_ = nullptr; + data.sharedPtrCount_ = nullptr; + data.weakPtrCount_ = nullptr; + } + + // Destructor + ~SharedPtr() { + Reset(); + } + +// Операторы, реализующие поведение указателей + // Присвоение (перемещение) + SharedPtr& operator=(const SharedPtr& data) { + if (this != &data) { + Reset(); // очистка + // присвоение новых значений + ptr_ = data.ptr_; + + sharedPtrCount_ = data.sharedPtrCount_; + weakPtrCount_ = data.weakPtrCount_; + if (sharedPtrCount_) { + (*sharedPtrCount_)++; + } + } + return *this; + } + + + SharedPtr& operator=(SharedPtr&& data) noexcept { + if (this != &data) { + Reset(); // очистка Метод UseCount - возвращает количество владельцев + ptr_ = data.ptr_; + // присвоение новых значений и обнуление data + sharedPtrCount_ = data.sharedPtrCount_; + weakPtrCount_ = data.weakPtrCount_; + data.ptr_ = nullptr; + data.sharedPtrCount_ = nullptr; + data.weakPtrCount_ = nullptr; + } + return *this; + } + + // укозатели + std::string& operator*() const { return *ptr_; } + std::string* operator->() const { return ptr_; } + + +// Методы + // Метод Get - получить сырой указатель + std::string* Get() const { return ptr_; } + + // Метод Reset - удаляет объект + void Reset() { + if (sharedPtrCount_ != nullptr) { // Есть, что очищать? + (*sharedPtrCount_)--; + + if (*sharedPtrCount_ == 0) { + delete ptr_; + ptr_ = nullptr; + + if (*weakPtrCount_ == 0) { + delete sharedPtrCount_; + delete weakPtrCount_; + } + } + + sharedPtrCount_ = nullptr; + weakPtrCount_ = nullptr; + } + ptr_ = nullptr; + + + } + + // Метод Reset - удаляет старый объект и принимает владение новым + void Reset(std::string* p) { + Reset(); // сброс + + // Присвоение + if (p) { // а есть что присвоить? + ptr_ = p; + sharedPtrCount_ = new size_t(1); + weakPtrCount_ = new size_t(0); + } + } + + // Метод Swap - обменивается владеющими указателями с другим WeakPtr + void Swap(SharedPtr& data) { + std::string* tempPtr; + size_t* temp; + + // Обмен указателями + tempPtr = data.ptr_; + data.ptr_ = ptr_; + ptr_ = tempPtr; + + + // Обмен счетчиком слабых ссылок + temp = data.sharedPtrCount_; + data.sharedPtrCount_ = sharedPtrCount_; + sharedPtrCount_ = temp; + + // Обмен счетчиком сильных ссылок + temp = data.weakPtrCount_; + data.weakPtrCount_ = weakPtrCount_; + weakPtrCount_ = temp; + } + + // Метод UseCount - возвращает количество владельцев + size_t UseCount() const { + if(sharedPtrCount_ != nullptr) return *sharedPtrCount_; + return 0; + } + + // Оператор bool() - приводит указатель к типу bool + operator bool() const { + if(ptr_ != nullptr) return true; + return false; + } + + // Friend classes + friend class WeakPtr; + friend void Swap(SharedPtr& lhs, SharedPtr& rhs); }; class WeakPtr { +private: + std::string* ptr_; // Указатель + size_t* sharedPtrCount_; // Счетчик сильных ссылок + size_t* weakPtrCount_; // Счетчик слабых ссылок + +public: + // Все необходимые конструкторы умного указателя с уникальным владением + // конструктор по умолчанию + WeakPtr() : ptr_(nullptr), sharedPtrCount_(nullptr), weakPtrCount_(nullptr) {} + + // конструктор от SharedPtr + WeakPtr(const SharedPtr& sp) : ptr_(sp.ptr_), sharedPtrCount_(sp.sharedPtrCount_), weakPtrCount_(sp.weakPtrCount_) { + if (weakPtrCount_) { + (*weakPtrCount_)++; + } + } + + // Конструктор копирования + WeakPtr(const WeakPtr& data) : ptr_(data.ptr_), sharedPtrCount_(data.sharedPtrCount_), weakPtrCount_(data.weakPtrCount_) { + if (weakPtrCount_) { + (*weakPtrCount_)++; + } + } + + // Конструктор перемещения + WeakPtr(WeakPtr&& data) noexcept : ptr_(data.ptr_), sharedPtrCount_(data.sharedPtrCount_), weakPtrCount_(data.weakPtrCount_) { + // Очищаем данные из которых переместили + data.ptr_ = nullptr; + data.sharedPtrCount_ = nullptr; + data.weakPtrCount_ = nullptr; + } + + // Диструктор + ~WeakPtr() { + Reset(); + } + + + WeakPtr& operator=(const WeakPtr& data) { + if (this != &data) { // текущий равен ? + // нет -присваивание. + Reset(); // очистка + ptr_ = data.ptr_; + sharedPtrCount_ = data.sharedPtrCount_; + weakPtrCount_ = data.weakPtrCount_; + if (weakPtrCount_) (*weakPtrCount_)++; + } + return *this; + } + + + WeakPtr& operator=(WeakPtr&& data) noexcept { + // аналогично как выше, но + очистка data + if (this != &data) { + Reset(); + ptr_ = data.ptr_; + sharedPtrCount_ = data.sharedPtrCount_; + weakPtrCount_ = data.weakPtrCount_; + // очистка data + data.ptr_ = nullptr; + data.sharedPtrCount_ = nullptr; + data.weakPtrCount_ = nullptr; + } + return *this; + } + + + WeakPtr& operator=(const SharedPtr& sp) { + // аналогично как выше + Reset(); + ptr_ = sp.ptr_; + sharedPtrCount_ = sp.sharedPtrCount_; + weakPtrCount_ = sp.weakPtrCount_; + if (weakPtrCount_) { + (*weakPtrCount_)++; + } + return *this; + } + + +// Методы + // Метод Reset - убирает ссылку на владеющий объект + void Reset() { + if (weakPtrCount_ != nullptr) { + (*weakPtrCount_ )--; + + if ((*sharedPtrCount_ == 0) && (*weakPtrCount_ == 0)) { + delete sharedPtrCount_; + delete weakPtrCount_; + } + + // очистка this + weakPtrCount_ = nullptr; + sharedPtrCount_ = nullptr; + ptr_ = nullptr; + } + } + + // Метод Swap - обменивается владеющими указателями с другим WeakPtr + void Swap(WeakPtr& data) { + std::string* tempPtr; + size_t* temp; + + // Обмен указателями + tempPtr = data.ptr_; + data.ptr_ = ptr_; + ptr_ = tempPtr; + + + // Обмен счетчиком слабых ссылок + temp = data.sharedPtrCount_; + data.sharedPtrCount_ = sharedPtrCount_; + sharedPtrCount_ = temp; + + // Обмен счетчиком сильных ссылок + temp = data.weakPtrCount_; + data.weakPtrCount_ = weakPtrCount_; + weakPtrCount_ = temp; + } + + + // Метод UseCount - возвращает количество владельцев + size_t UseCount() const { + if(sharedPtrCount_ != nullptr) return *sharedPtrCount_; + return 0; + } + + // Метод Expired - проверяет, истекло ли время жизни исходного объекта + bool Expired() const { + if(sharedPtrCount_ == nullptr) return true; // указатель на nullptr значит истекло время жизни + if(*sharedPtrCount_ != 0) return false; // счетчик не 0 значит не истекло время жизни + return true; // счетчик = 0 значит истекло время жизни + } + + // Метод Lock - создает владеющий указатель SharedPtr на объект, если он ещё жив + SharedPtr Lock() const { + if (!Expired()) { + SharedPtr sp; + sp.ptr_ = ptr_; + sp.sharedPtrCount_ = sharedPtrCount_; + sp.weakPtrCount_ = weakPtrCount_; + if (sp.sharedPtrCount_ != nullptr) { + (*sp.sharedPtrCount_)++; + } + return sp; + } + return SharedPtr(); + } + + // Friend functions + friend void Swap(WeakPtr& lhs, WeakPtr& rhs); +}; + + + + +// Функия MakeShared - принимает строку и возвращает умный указатель SharedPtr. Функция должна поддерживать как копирование, так и перемещение принимаемого объекта. +SharedPtr MakeShared(const std::string& str) { + return SharedPtr(new std::string(str)); +} + +SharedPtr MakeShared(std::string&& str) { + return SharedPtr(new std::string(std::move(str))); +} + +// Функция Swap - для обмена умными указателями SharedPtr, и указателями WeakPtr +void Swap(SharedPtr& dataA, SharedPtr& dataB) { + dataA.Swap(dataB); +} -}; \ No newline at end of file +void Swap(WeakPtr& dataA, WeakPtr& dataB) { + dataA.Swap(dataB); +} From 6fcb27c377ecb3d51fc6c3746122b9fae9db9b2f Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Tue, 10 Mar 2026 22:12:51 +0500 Subject: [PATCH 64/65] Update array.cpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit решение array --- 07_week/tasks/array/array.cpp | 251 +++++++++++++++++++++++++++++++++- 1 file changed, 250 insertions(+), 1 deletion(-) diff --git a/07_week/tasks/array/array.cpp b/07_week/tasks/array/array.cpp index b1b8feab..99b962d4 100644 --- a/07_week/tasks/array/array.cpp +++ b/07_week/tasks/array/array.cpp @@ -1,6 +1,255 @@ #include +/* +Массив на стеке +Необходимо реализовать класс Array, представляющий реализацию массива на стеке для элементов произвольного типа. + +Класс предоставляет следующий функционал: + + Конструктор по умолчанию + Конструктор, принимающий список инициализации std::initializer_list + Конструктор копирования + Конструктор перемещения + Операторы присваивания копированием + Оператор присваивания перемещением + Деструктор + Операторы индексирования []- обеспечивают доступ по ссылке к элементу контейнера + Метод Front - возвращает ссылку на первый элемент массива, для пустого массива UB + Метод Back - возвращает ссылку на последний элемент массива, для пустого массива UB + Метод Data - прямой доступ к памяти, для константного контейнера изменять данные нельзя + Метод Empty - возвращает true, если контейнер пуст + Метод Size - возвращает размер контейнера + Метод Fill - заполняет контейнер определенным элементом + Метод Swap - обменивается содержимым с другим аналогичным контейнером. + Поддержка работы range-based for для контейнера. В данном случае для простоты допустимо возвращать указатели на первый элемент и за последний, концепция итераторов будет обсуждаться позже. Необходимо реализовать методы begin, end + Методы cbegin, cend - возвращающие указатель на соответствующий константный элемент + +Внешние функции: + + Операторы сравнения на равенство и неравенство + Операторы сравнения на больше, меньше, больше или равно, меньше или равно, производящие лексикографическое сравнение + Функция swap - обменивается содержимым с другим аналогичным контейнером. + Функция get - обращение к элементу аналогично кортежу. Имеет дополнительный параметр шаблона I для порядкового номера элемента. Может работать с временным массивом. Позволяет изменять элементы для неконстантного массива. + +Примечание + + Запрещено использовать стандартные контейнеры (std::vector, std::array, ...) + Даже если используются default конструкторы, генерируемые компилятором, необходимо явно их создать + Некоторые методы могут иметь константные и неконстантные версии + Для поддержки range-based for необходимы методы begin, end или внешние функции begin, end, принимающие заданную коллекцию, поэтому допустимо, чтобы они не соответствовали стайлгайду. Если не хочется нарушать стайлгайд, то методы класса могут быть с большой буквы, но внешние функции должны быть с маленькой + Для совместимости с алгоритмами стандартной библиотеки STL может потребоваться swap, ситуация аналогичная, но поскольку требуется внутри класса Swap, достаточно реализовать внешнюю функцию, вызывающую метод Swap контейнера + + +*/ + + + +// для работы с любым типом данных создаем шаблон. далее он будет заменен на нужный тип при компиляции кода с конкретным применением класса +template class Array { +private: + T data_[N]; // Массив данных пока не определенного типа вернее типа определяемого из контекста в момент компиляции. + +public: + + // Конструктор по умолчанию, default - значит за меня его соберет компилятор. На данном этапе тип данных с которым работаем не известен. + Array() = default; + + // Конструктор, принимающий список инициализации std::initializer_list + Array(std::initializer_list list) { + size_t i = 0; + for (auto pos = list.begin(); pos != list.end() && i < N; ++pos, ++i) data_[i] = *pos; + // исп. auto т.к. для автоматического определения типа данных. + // Проходим от начала и до конца запоминая значения. + } + + // Конструктор копирования + Array(const Array& data) { + for (std::size_t i = 0; i < N; ++i) data_[i] = data.data_[i]; // копирование всех элементов + } + + // Конструктор перемещения + Array(Array&& data) noexcept { // такое было в предыдущих заданиях + for (std::size_t i = 0; i < N; ++i) data_[i] = std::move(data.data_[i]); + } + + // Операторы присваивания копированием + Array& operator=(const Array& data) { + if (this != &data) { // првоерка, что не копируем сами себя. + for (std::size_t i = 0; i < N; ++i) data_[i] = data.data_[i]; // копируем + } + // иначе смысла копировать нет. + return *this; + } + + // Оператор присваивания перемещением + Array& operator=(Array&& data) noexcept { + if (this != &data) { // првоерка, что не копируем сами себя. + for (std::size_t i = 0; i < N; ++i) data_[i] = std::move(data.data_[i]); + } + return *this; + } + +// Деструктор + ~Array() = default; // диструктор по умолчанию, default - значит за меня его соберет компилятор. На данном этапе тип данных с которым работаем не известен. + + // Операторы индексирования []- обеспечивают доступ по ссылке к элементу контейнера + T& operator[](std::size_t i) { + return data_[i]; + } + + // перегрузка для const + const T& operator[](std::size_t index) const { + return data_[index]; + } + +/*---- МЕТОДЫ----*/ + + // Метод Front - возвращает ссылку на первый элемент массива, для пустого массива UB + T& Front() { return data_[0]; } + + // перегрузка для const + const T& Front() const { return data_[0]; } + + // Доступ к последнему элементу + T& Back() { return data_[N - 1];} + + +// Метод Back - возвращает ссылку на последний элемент массива, для пустого массива UB + const T& Back() const { return data_[N - 1];} + +// Метод Data - прямой доступ к памяти, для константного контейнера изменять данные нельзя + T* Data() { return data_;} // для константного контейнера изменять данные нельзя + const T* Data() const { return data_; } + +// Метод Empty - возвращает true, если контейнер пуст + bool Empty() const { return N == 0; } + +// Метод Size - возвращает размер контейнера + std::size_t Size() const { return N; } + +// Метод Fill - заполняет контейнер определенным элементом + void Fill(const T& data) { + for (std::size_t i = 0; i < N; ++i) data_[i] = data; + } + +// Метод Swap - обменивается содержимым с другим аналогичным контейнером. + void Swap(Array& data) noexcept { + for (std::size_t i = 0; i < N; ++i) std::swap(data_[i], data.data_[i]); + } + +/* + Поддержка работы range-based for для контейнера. В данном случае для простоты допустимо возвращать указатели на первый элемент и за последний, концепция итераторов будет обсуждаться позже. Необходимо реализовать методы begin, end + Методы cbegin, cend - возвращающие указатель на соответствующий константный элемент +*/ + + // Итераторы для range-based for + T* begin() { return data_; } + + // перегрузка для const + const T* begin() const { return data_; } + + T* end() { return data_ + N; } + + const T* end() const { return data_ + N; } + + // Константные итераторы + const T* cbegin() const { return data_; } + + const T* cend() const { return data_ + N; } +}; + + +/* + + Операторы сравнения на равенство и неравенство + Операторы сравнения на больше, меньше, больше или равно, меньше или равно, производящие лексикографическое сравнение + Функция swap - обменивается содержимым с другим аналогичным контейнером. + Функция get - обращение к элементу аналогично кортежу. Имеет дополнительный параметр шаблона I для порядкового номера элемента. Может работать с временным массивом. Позволяет изменять элементы для неконстантного массива. + +*/ + + +// Операторы сравнения на равенство и неравенство + template + // равенство - первое базовое сравнение + bool operator==(const Array& dataA, const Array& dataB) { // равенство + for (std::size_t i = 0; i < N; ++i) if (dataA[i] != dataB[i]) return false; + // Сравнили все и все совпало. + return true; + } + + template + bool operator!=(const Array& dataA, const Array& dataB) { + return !(dataA == dataB); // идем от обратного + } + +// Операторы сравнения на больше, меньше, больше или равно, меньше или равно, производящие лексикографическое сравнение +// + template + bool operator > (const Array& dataA, const Array& dataB) { // меньше + for (std::size_t i = 0; i < N; ++i) { + if (dataA[i] > dataB[i]) return true; // значение больше, возвращаем true + if (dataA[i] < dataB[i]) return false; // значение меньше, возвращаем false + } + + // значения равны, возвращаем false + return false; + } + + // А < В это аналогично В > А, оператор ">" определен выше + template + bool operator < (const Array& dataA, const Array& dataB) { + return dataB > dataA; + } + + // А <= В это аналогично !(А > В), оператор ">" определен выше + template + bool operator <= (const Array& dataA, const Array& dataB) { + return !(dataA > dataB); // идем от обратного + } + + +// А >= В это аналогично !(А < В), оператор "<" определен выше +template +bool operator >= (const Array& dataA, const Array& dataB) { + return !(dataA < dataB); +} + +// Функция swap - обменивается содержимым с другим аналогичным контейнером. +template +void swap(Array& dataA, Array& dataB) noexcept { + dataA.Swap(dataB); +} + + + +// Функция get - обращение к элементу аналогично кортежу. Имеет дополнительный параметр шаблона I для порядкового номера элемента. Может работать с временным массивом. Позволяет изменять элементы для неконстантного массива. +template +struct GetHelper { + static T& get(Array& arr) { return arr[I]; } + + static const T& get(const Array& arr) { return arr[I]; } + + static T&& get(Array&& arr) { return std::move(arr[I]); } +}; + +// Функция get для доступа по индексу массива +template +auto get(Array& arr) -> decltype(GetHelper::get(arr)) { + + return GetHelper::get(arr); +} + +template +auto get(const Array& arr) -> decltype(GetHelper::get(arr)) { + + return GetHelper::get(arr); +} -}; \ No newline at end of file +template +auto get(Array&& arr) -> decltype(GetHelper::get(std::move(arr))) { + + return GetHelper::get(std::move(arr)); +} From 8c10777c14a830743a764f4de5c0e5ec9f8892bb Mon Sep 17 00:00:00 2001 From: Evgenii Sh <79617771614@yandex.ru> Date: Tue, 10 Mar 2026 22:55:52 +0500 Subject: [PATCH 65/65] Update make_unique.cpp --- 07_week/tasks/make_unique/make_unique.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/07_week/tasks/make_unique/make_unique.cpp b/07_week/tasks/make_unique/make_unique.cpp index e0fdcbd7..5b6ff19b 100644 --- a/07_week/tasks/make_unique/make_unique.cpp +++ b/07_week/tasks/make_unique/make_unique.cpp @@ -1,4 +1,16 @@ #include - - -/* return_type */ MakeUnique( /* args */ ); +/* +* +* Создаем умный указатель std::unique_ptr на новый объект типа T +* где: +* T Тип создаваемого объекта +* data- типы аргументов для конструктора +* x - аргументы для конструктора объекта типа T +* std::unique_ptr - умный указатель, владеющий созданным объектом. Важно !! без этого не пройти тесты или надо комментировать строку 133 и 134 т.к. там тест конкретно ждет * std::unique_ptr +* + */ +template +std::unique_ptr MakeUnique(Data&&... x) { + // Выделяем память и конструируем объект + return std::unique_ptr(new T(std::forward(x)...)); +}