Я смотрел видео на Youtube, где какой-то стад демонстрирует разные алгоритмы нахождения медианы двух отсортированных массивов: алгоритм подробно описан здесь: https://www.youtube.com/watch?v=_H50Ir-Tves. Я пытаюсь реализовать его алгоритм «Сравнение медиан» и сталкиваюсь с проблемой столба забора или что-то в этом роде. Я решил, что должен просто определить «медиану» как элемент N/2
в массиве из N
элементов. Моя реализация в целом грязная и не работает.
Вот функция, которую я использую для сравнения моей другой функции:
template <typename T>
T M2SA_Dumb(std::vector<T> A, std::vector<T> B)
{
if (A.size() == 0 || B.size() == 0)
throw std::invalid_argument("Can't find median of 2 sorted arrays if both are empty!");
std::vector<T> AB;
AB.reserve(A.size() + B.size());
AB.insert(AB.end(), A.begin(), A.end());
AB.insert(AB.end(), B.begin(), B.end());
sort(AB.begin(), AB.end());
return (AB[AB.size() / 2]);
}
И вот моя неработающая функция, которую я пытаюсь отладить:
template <typename T>
T M2SA_Smart(const std::vector<T> & A, const std::vector<T> & B)
{
size_t m(A.size()), n(B.size());
T retval;
size_t sizeval = (m > 0 ? 1 : 0) + 2 * (n > 0 ? 1 : 0);
switch (sizeval)
{
case 0: // A, B empty
throw std::invalid_argument("Can't find median of 2 sorted arrays if both are empty!");
break;
case 1: // A non-empty, B empty
retval = A[m / 2];
break;
case 2: // A empty, B non-empty
retval = B[n / 2];
break;
default: // A, B non-empty
size_t medidx = (m + n) / 2;
if (A[m - 1] <= B[0])
{
if (medidx >= m)
{
retval = B[medidx - m];
}
else
{
retval = A[medidx];
}
}
else if (B[n - 1] <= A[0])
{
if (medidx >= n)
{
retval = A[medidx - n];
}
else
{
retval = B[medidx];
}
}
else
{
size_t a1(0), a2(m - 1), b1(0), b2(n - 1);
T M1(A[(a2 - a1) / 2]), M2(B[(b2 - b1) / 2]);
while (a1 != a2 && b1 != b2)
{
if (M1 == M2)
{
retval = M1;
break;
}
else if (M1 < M2)
{
a1 = (a2 - a1) / 2;
b2 = (b2 - b1) / 2;
}
else
{
a2 = (a2 - a1) / 2;
b1 = (b2 - b1) / 2;
}
M1 = A[(a2 - a1) / 2];
M2 = B[(b2 - b1) / 2];
}
retval = std::max(M1, M2);
}
break;
}
return retval;
}
Я думаю, что проблема в рекурсивной части
{
size_t a1(0), a2(m - 1), b1(0), b2(n - 1);
T M1(A[(a2 - a1) / 2]), M2(B[(b2 - b1) / 2]);
while (a1 != a2 && b1 != b2)
{
if (M1 == M2)
{
retval = M1;
break;
}
else if (M1 < M2)
{
a1 = (a2 - a1) / 2;
b2 = (b2 - b1) / 2;
}
else
{
a2 = (a2 - a1) / 2;
b1 = (b2 - b1) / 2;
}
M1 = A[(a2 - a1) / 2];
M2 = B[(b2 - b1) / 2];
}
retval = std::max(M1, M2);
}
Происходит что-то неладное. Любая идея, что это???
Для дополнительной информации,
я тестировал
std::vector<int> v1 = { 1, 1, 69, 111, 124 };
std::vector<int> v2 = { 40, 50, 60, 70, 80, 90, 100, 110, 120, 130 };
и получил
M2SA_Dumb(v1, v2) = 80
(правильный ответ)
а также
M2SA_Dumb(v1, v2) = 40
(неправильный ответ)