From 55881d406290b5af66b41e2957d7df52e4b86ba2 Mon Sep 17 00:00:00 2001 From: chatlanin Date: Thu, 13 Mar 2025 08:59:32 +0300 Subject: [PATCH] add pow --- README.md | 4 +- bin/main.cpp | 46 +++++++++++++------ src/base/insertion_sort.hpp | 2 +- src/base/merge_sort.hpp | 38 ++++++++++++++++ src/base/merge_sort.v1.hpp | 84 +++++++++++++++++++++++++++++++++++ src/base/merge_sort.v2.hpp | 67 ++++++++++++++++++++++++++++ src/numbers/gcd.hpp | 2 +- src/numbers/pow.hpp | 23 ++++++++++ src/numbers/prime_factors.hpp | 2 +- 9 files changed, 250 insertions(+), 18 deletions(-) create mode 100644 src/base/merge_sort.hpp create mode 100644 src/base/merge_sort.v1.hpp create mode 100644 src/base/merge_sort.v2.hpp create mode 100644 src/numbers/pow.hpp diff --git a/README.md b/README.md index d7719c9..37ae518 100644 --- a/README.md +++ b/README.md @@ -4,4 +4,6 @@ 1. Сортировка вставками 2. Нахождение наибольшего общего делителя -3. Нахождение все простых множителей заданного числа. +3. Нахождение все простых множителей заданного числа. (в работе) +4. Сортировка слиянием. (в работе) +5. Возведение в степень. (в работе) diff --git a/bin/main.cpp b/bin/main.cpp index 58835dc..cad6531 100644 --- a/bin/main.cpp +++ b/bin/main.cpp @@ -1,27 +1,45 @@ #include #include "base/insertion_sort.hpp" +#include "base/merge_sort.hpp" +#include "base/merge_sort.v2.hpp" #include "numbers/gcd.hpp" #include "numbers/prime_factors.hpp" +#include "numbers/pow.hpp" auto main() -> int { + { + hack::log()(alg::pow(3.0, 2), alg::pow(3.0, 3)); + return 1; + } + + { + std::vector v { 5, 4, 1, 5, 6 }; + alg::insertion_sort(v); + hack::log()(v); + } - // std::vector v { 2, 5, 4, 6, 1, 3 }; - std::vector v { 5, 4, 1, 5, 6 }; - algorithms::insertion_sort(v); - hack::log()(v); + { + std::vector v { 16, 7, 10, 1, 5, 11, 3, 8, 14, 4, 2, 12, 6, 13, 9, 15 }; + alg_v2::merge_sort(v); + hack::log()(v); + } - // hack::log()(algorithms::gcd(4851, 3003)); - // hack::log()(algorithms::gcd(64, 28)); - // - // hack::log()(algorithms::prime_factors_v1(127)); - // hack::log()(algorithms::prime_factors_v1(128)); - // hack::log()(algorithms::prime_factors_v1(130)); - // - // hack::log()(algorithms::prime_factors_v2(127)); - // hack::log()(algorithms::prime_factors_v2(128)); - // hack::log()(algorithms::prime_factors_v2(130)); + { + hack::log()(alg::gcd(4851, 3003)); + hack::log()(alg::gcd(64, 28)); + } + + { + hack::log()(alg::prime_factors_v1(127)); + hack::log()(alg::prime_factors_v1(128)); + hack::log()(alg::prime_factors_v1(130)); + + hack::log()(alg::prime_factors_v2(127)); + hack::log()(alg::prime_factors_v2(128)); + hack::log()(alg::prime_factors_v2(130)); + } } diff --git a/src/base/insertion_sort.hpp b/src/base/insertion_sort.hpp index 3d09fb9..c2517aa 100644 --- a/src/base/insertion_sort.hpp +++ b/src/base/insertion_sort.hpp @@ -5,7 +5,7 @@ // Сортировка вставкой // Эффективна на мелких массивах. Сложнгость O(N^2) -namespace algorithms +namespace alg { inline void insertion_sort(std::vector& v) { diff --git a/src/base/merge_sort.hpp b/src/base/merge_sort.hpp new file mode 100644 index 0000000..24beec3 --- /dev/null +++ b/src/base/merge_sort.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include +#include + +// Сортировка вставкой +// Эффективна на мелких массивах. Сложнгость O(N^2) +namespace alg +{ + inline void merge(std::vector& v, int left, int mid, int right, std::vector& tmp) + { + for(int i = left, j = mid + 1; left <= right; ++left) + { + bool useRight = i > mid || (j <= right && tmp[j] < tmp[i]); + v[left] = tmp[(useRight ? j : i)++]; + } + } + + inline void merge_sort_helper(std::vector& v, int left, int right, std::vector& tmp) + { + if (left < right) + { + int mid = (left + right) / 2; + + merge_sort_helper(tmp, left, mid, v); + merge_sort_helper(tmp, mid + 1, right, v); + + merge(v, left, mid, right, tmp); + } + } + + inline void merge_sort(std::vector& v) + { + std::vector tmp(v); + merge_sort_helper(v, 0, v.size() - 1, tmp); + } +} + diff --git a/src/base/merge_sort.v1.hpp b/src/base/merge_sort.v1.hpp new file mode 100644 index 0000000..e82e056 --- /dev/null +++ b/src/base/merge_sort.v1.hpp @@ -0,0 +1,84 @@ +#pragma once + +#include +#include +#include "insertion_sort.hpp" + +// Сортировка вставкой +// Эффективна на мелких массивах. Сложнгость O(N^2) +namespace alg_v1 +{ + // Функция для слияния двух отсортированных половин массива + inline void merge(std::vector& v, int start1, int end1, int start2, int end2) + { + auto fs = start1; + auto fe = end2; + + int i = 1; + + std::vector tmp(v); + + while (start1 <= end1 && (start2 <= end2)) + { + if (v[start1] < v[start2]) + { + tmp[i] = v[start1]; + ++start1; + } + else + { + tmp[i] = v[start2]; + ++start2; + } + ++i; + } + + if (start1 <= end1) + { + for (int j = start1; j < end1; ++j) + { + tmp[i] = v[j]; + ++i; + } + } + else + { + for (int j = start2; j < end2; ++j) + { + tmp[i] = v[j]; + ++i; + } + } + + i = 1; + for (int j = fs; j < fe; ++j) + { + v[j] = tmp[i]; + ++i; + } + } + + inline void merge_sort_helper(int i, std::vector& v, int first, int last) + { + if (first < last) + { + // Находим среднюю точку + int mid = (first + last) / 2; + + hack::log()(i, " | first =", first, ", last =", last, ", mid =", mid); + + // Сортируем первую и вторую половины + merge_sort_helper(1, v, first, mid); + merge_sort_helper(2, v, mid + 1, last); + + // Сливаем отсортированные половины + merge(v, first, mid, mid + 1, last); + } + } + + inline void merge_sort(std::vector& v) + { + merge_sort_helper(0, v, 0, v.size() - 1); + } +} + diff --git a/src/base/merge_sort.v2.hpp b/src/base/merge_sort.v2.hpp new file mode 100644 index 0000000..444418d --- /dev/null +++ b/src/base/merge_sort.v2.hpp @@ -0,0 +1,67 @@ +#pragma once + +#include +#include +#include "insertion_sort.hpp" + +// Сортировка вставкой +// Эффективна на мелких массивах. Сложнгость O(N^2) +namespace alg_v2 +{ + inline void merge(std::vector& v, int left, int mid, int right) + { + std::vector l(v.begin() + left, v.begin() + mid + 1); + std::vector r(v.begin() + mid + 1, v.begin() + right + 1); + + int i = 0; // индекс для левой подсистемы + int j = 0; // индекс для правой подсистемы + int k = left; // индекс для A[p:r+1] + + // Объединение двух отсортированных подсистем + while (i < l.size() && j < r.size()) + { + if (l[i] <= r[j]) { + v[k] = l[i]; + i++; + } else { + v[k] = r[j]; + j++; + } + k++; + } + + // Копирование оставшихся элементов левой подсистемы (если есть) + while (i < l.size()) + { + v[k] = l[i]; + i++; + k++; + } + + // Копирование оставшихся элементов правой подсистемы (если есть) + while (j < r.size()) { + v[k] = r[j]; + j++; + k++; + } + } + + inline void merge_sort_helper(std::vector& v, int left, int right) + { + if (left < right) + { + int mid = (left + right) / 2; + + merge_sort_helper(v, left, mid); + merge_sort_helper(v, mid + 1, right); + + merge(v, left, mid, right); + } + } + + inline void merge_sort(std::vector& v) + { + merge_sort_helper(v, 0, v.size() - 1); + } +} + diff --git a/src/numbers/gcd.hpp b/src/numbers/gcd.hpp index be950d7..4ba06f8 100644 --- a/src/numbers/gcd.hpp +++ b/src/numbers/gcd.hpp @@ -2,7 +2,7 @@ // Называется алгоритм Евклида // Находит наибольший общий делитель -namespace algorithms +namespace alg { inline int gcd(int a, int b) { diff --git a/src/numbers/pow.hpp b/src/numbers/pow.hpp new file mode 100644 index 0000000..43e1cd1 --- /dev/null +++ b/src/numbers/pow.hpp @@ -0,0 +1,23 @@ +#pragma once + +// Возведение в степень +namespace alg +{ + inline int pow(double a, int n) + { + double result = 1.0; + bool is_negative = n < 0; + + if (is_negative) n *= -1; + + while (n > 0) + { + if (n & 1) result *= a; + a *= a; + n >>= 1; + } + + return is_negative ? 1.0 / result : result; + } +} + diff --git a/src/numbers/prime_factors.hpp b/src/numbers/prime_factors.hpp index 3f8abb2..4247f1c 100644 --- a/src/numbers/prime_factors.hpp +++ b/src/numbers/prime_factors.hpp @@ -5,7 +5,7 @@ // Находит все простые множители заданного числа. // Простое число - это число > 1, которое делится на 1 и на само себя. -namespace algorithms +namespace alg { inline std::vector prime_factors_v1(int a) {