This commit is contained in:
2025-03-13 08:59:32 +03:00
parent 80dfb901a1
commit 55881d4062
9 changed files with 250 additions and 18 deletions

View File

@@ -4,4 +4,6 @@
1. Сортировка вставками
2. Нахождение наибольшего общего делителя
3. Нахождение все простых множителей заданного числа.
3. Нахождение все простых множителей заданного числа. (в работе)
4. Сортировка слиянием. (в работе)
5. Возведение в степень. (в работе)

View File

@@ -1,27 +1,45 @@
#include <hack/logger/logger.hpp>
#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<int> v { 2, 5, 4, 6, 1, 3 };
{
std::vector<int> v { 5, 4, 1, 5, 6 };
algorithms::insertion_sort(v);
alg::insertion_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));
{
std::vector<int> 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()(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));
}
}

View File

@@ -5,7 +5,7 @@
// Сортировка вставкой
// Эффективна на мелких массивах. Сложнгость O(N^2)
namespace algorithms
namespace alg
{
inline void insertion_sort(std::vector<int>& v)
{

38
src/base/merge_sort.hpp Normal file
View File

@@ -0,0 +1,38 @@
#pragma once
#include <vector>
#include <hack/logger/logger.hpp>
// Сортировка вставкой
// Эффективна на мелких массивах. Сложнгость O(N^2)
namespace alg
{
inline void merge(std::vector<int>& v, int left, int mid, int right, std::vector<int>& 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<int>& v, int left, int right, std::vector<int>& 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<int>& v)
{
std::vector<int> tmp(v);
merge_sort_helper(v, 0, v.size() - 1, tmp);
}
}

View File

@@ -0,0 +1,84 @@
#pragma once
#include <vector>
#include <hack/logger/logger.hpp>
#include "insertion_sort.hpp"
// Сортировка вставкой
// Эффективна на мелких массивах. Сложнгость O(N^2)
namespace alg_v1
{
// Функция для слияния двух отсортированных половин массива
inline void merge(std::vector<int>& v, int start1, int end1, int start2, int end2)
{
auto fs = start1;
auto fe = end2;
int i = 1;
std::vector<int> 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<int>& 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<int>& v)
{
merge_sort_helper(0, v, 0, v.size() - 1);
}
}

View File

@@ -0,0 +1,67 @@
#pragma once
#include <vector>
#include <hack/logger/logger.hpp>
#include "insertion_sort.hpp"
// Сортировка вставкой
// Эффективна на мелких массивах. Сложнгость O(N^2)
namespace alg_v2
{
inline void merge(std::vector<int>& v, int left, int mid, int right)
{
std::vector<int> l(v.begin() + left, v.begin() + mid + 1);
std::vector<int> 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<int>& 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<int>& v)
{
merge_sort_helper(v, 0, v.size() - 1);
}
}

View File

@@ -2,7 +2,7 @@
// Называется алгоритм Евклида
// Находит наибольший общий делитель
namespace algorithms
namespace alg
{
inline int gcd(int a, int b)
{

23
src/numbers/pow.hpp Normal file
View File

@@ -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;
}
}

View File

@@ -5,7 +5,7 @@
// Находит все простые множители заданного числа.
// Простое число - это число > 1, которое делится на 1 и на само себя.
namespace algorithms
namespace alg
{
inline std::vector<int> prime_factors_v1(int a)
{