C++ 使用“";“比较中间值”;程序和C++;
我在看一段Youtube视频,其中一些研究人员演示了查找2个排序数组中值的不同算法:此处详述的算法:。 我正试图实现他的“比较中间值”算法,结果遇到了一个栅栏柱之类的问题。我决定将“中间值”定义为C++ 使用“";“比较中间值”;程序和C++;,c++,algorithm,median,C++,Algorithm,Median,我在看一段Youtube视频,其中一些研究人员演示了查找2个排序数组中值的不同算法:此处详述的算法:。 我正试图实现他的“比较中间值”算法,结果遇到了一个栅栏柱之类的问题。我决定将“中间值”定义为N元素数组中的元素N/2。我的实现总体上是混乱的,不起作用 下面是我用来比较其他函数的函数: template <typename T> T M2SA_Dumb(std::vector<T> A, std::vector<T> B) { if (A.size
N
元素数组中的元素N/2
。我的实现总体上是混乱的,不起作用
下面是我用来比较其他函数的函数:
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]);
}
模板
T M2SA_Dumb(标准::向量A,标准::向量B)
{
如果(A.size()==0 | | B.size()==0)
throw std::无效的_参数(“如果两个排序数组都为空,则找不到它们的中间值!”);
std::载体AB;
AB.保留(A.尺寸()+B.尺寸());
AB.插入(AB.结束(),A.开始(),A.结束());
AB.插入(AB.结束(),B.开始(),B.结束());
排序(AB.begin(),AB.end());
返回(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;
}
模板
T M2SA_智能(常数标准::向量和A,常数标准::向量和B)
{
尺寸m(A.size()),n(B.size());
T回顾;
大小大小=(m>0?1:0)+2*(n>0?1:0);
开关(sizeval)
{
案例0://A,B为空
throw std::无效的_参数(“如果两个排序数组都为空,则找不到它们的中间值!”);
打破
案例1://A非空,B为空
retval=A[m/2];
打破
案例2://A为空,B为非空
retval=B[n/2];
打破
默认值://A,B非空
尺寸_tmedidx=(m+n)/2;
如果(A[m-1]=m)
{
retval=B[medidx-m];
}
其他的
{
retval=A[medidx];
}
}
else如果(B[n-1]=n)
{
retval=A[medidx-n];
}
其他的
{
retval=B[medidx];
}
}
其他的
{
尺寸a1(0),a2(m-1),b1(0),b2(n-1);;
t1(A[(a2-a1)/2]),M2(B[(b2-b1)/2]);
而(a1!=a2&&b1!=b2)
{
如果(M1==M2)
{
retval=M1;
打破
}
否则如果(M1
我认为问题在于递归部分
{
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);
}
{
尺寸a1(0),a2(m-1),b1(0),b2(n-1);;
t1(A[(a2-a1)/2]),M2(B[(b2-b1)/2]);
而(a1!=a2&&b1!=b2)
{
如果(M1==M2)
{
retval=M1;
打破
}
否则如果(M1
发生了一些奇怪的事情。知道是什么吗
要了解更多信息
我测试了
std::vector<int> v1 = { 1, 1, 69, 111, 124 };
std::vector<int> v2 = { 40, 50, 60, 70, 80, 90, 100, 110, 120, 130 };
std::vector v1={1,1,69,111,124};
向量v2={40,50,60,70,80,90,100,110,120,130};
得到
M2SA_Dumb(v1,v2)=80
(正确答案)
及
M2SA_Dumb(v1,v2)=40
(错误答案)视频中显示的算法适用于两个大小相同的数组或向量。此外,偶数元素数组的中值通常定义为两个中间元素的平均值(因此它可能是以.5结尾的浮点值)
链接到不同大小数组的更通用算法:
我不确定这是否可行。在大多数当前PC上,使用合并排序或快速排序,400万个64位整数的数组或向量可以在不到1秒的时间内进行排序。STD::合并两个排序的数组或向量或STD::清单:合并两个排序的列表只需很小的一秒。您应该认真考虑更改用户名。当从算法的递归部分中的向量修剪元素时,从每个向量中移除的元素的数量需要相同。因此,如果从一个向量的第一部分移除x元素,那么从另一个向量的最后部分移除x元素。逻辑需要处理向量大小不同的情况。与其递归地创建新向量,不如在每个向量的开头和结尾使用索引。