需要帮助为我的算法中的缺陷提供优雅的修复
Need help coming up with elegant fix for flaw in my algorithm
我正在为一家大型在线零售商的面试进行练习,现在正试图为"两个排序数组的中值"问题找到一个优雅的解决方案。我知道youtube上提供的解决方案,但我正在尝试写一个替代方案。我已经写出
include <stdio.h>
int M2SA ( int * A, int m, int * B, int n )
{
/* Returns the median of two sorted arrays A and B of lengths m and n respectively.
Assumes A and B aren't both empty.
*/
int ida = 0, idb = 0, idmed = (m+n)/2;
while ((ida + idb) != idmed)
{
if (A[ida] < B[idb])
++ida;
else
++idb;
}
return (A[ida] < A[idb] ? A[ida] : B[idb]);
}
int main()
{
int arr1 [] = {1, 1, 59, 69};
int arr2 [] = {-4, 0, 49, 59, 59, 59};
printf("%d", M2SA(arr1, sizeof(arr1)/sizeof(int), arr2, sizeof(arr2)/sizeof(int)));
return 0;
}
它打印出正确的答案(59
),但我意识到有一个缺陷,即我的算法只有在idmed
不大于m
或n
时才有效。例如,如果数组是{1}
和{69, 293, 393, 1923129}
,则在while
循环的第一次迭代之后,ida
等于1
,因此while循环的第二次迭代尝试访问A[1]
。然而,我想不出一个简单的修复程序可以添加到我的代码中。有简单的吗?
以下是对您的解决方案的一个优雅修复:
int ida = 0, idb = 0, idmed = (m + n) / 2;
while (ida < m && idb < n && ida + idb < idmed) {
A[ida] < B[idb] ? ++ida : ++idb;
}
if (ida == m) return B[idmed - m];
if (idb == n) return A[idmed - n];
return A[ida] < B[idb] ? A[ida] : B[idb];
基本上有3种情况需要考虑:
- 两个数组都没有被完全消耗
- 第一个数组已被消耗,中位数在第二个数组中
- 第二个数组已被消耗,中位数在第一个数组中
实施必须注意这3种情况。这3种情况中的哪一种被触发取决于输入数据。
例如,如果所有较小的值都在数组1中,而较大的值在数组2中,并且数组1的长度短于数组2的长度,则数组1中的索引处于数组1长度。因此访问它不是一个好主意。
这里是一个使用for循环而不是while的实现。我更喜欢这里的循环,因为更容易看到循环最终会终止。
main()函数包含一组测试用例,它们触发上面提到的所有三个代码路径。
int
m2a
( _In_reads_(s1) const int * a1
, int s1
, _In_reads_(s2) const int *a2
, int s2
)
{
int mi = (s1 + s2) / 2;
int ai1 = 0;
int ai2 = 0;
for (int i = 0; i < mi;i++)
{
if (ai1 < s1 && ai2 < s2)
{
if (a1[ai1] < a2[ai2])
{
ai1++;
}
else
{
ai2++;
}
}
else
{
if (ai1 < s1)
{
ai1++;
}
if (ai2 < s2)
{
ai2++;
}
}
}
int result = 0;
if (ai1 < s1 && ai2 < s2)
{
result = a1[ai1] < a2[ai2] ? a1[ai1] : a2[ai2];
}
else
{
if (ai1 < s1)
{
result = a1[ai1];
}
if (ai2 < s2)
{
result = a2[ai2];
}
}
return result;
}
int _tmain(int argc, _TCHAR* argv[])
{
{
const int s1 = 4;
const int s2 = 4;
int a1[s1] = { 1, 2, 3, 4 };
int a2[s2] = { 1, 2, 3, 4 };
int m = m2a(a1, s1, a2, s2);
printf("%dn", m);
}
{
const int s1 = 5;
const int s2 = 4;
int a1[s1] = { 5,6,7,8,9 };
int a2[s2] = { 1, 2, 3, 4 };
int m = m2a(a1, s1, a2, s2);
printf("%dn", m);
}
{
const int s1 = 4;
const int s2 = 5;
int a1[s1] = { 1, 2, 3, 4 };
int a2[s2] = { 5, 6, 7, 8, 9 };
int m = m2a(a1, s1, a2, s2);
printf("%dn", m);
}
{
const int s1 = 1;
const int s2 = 5;
int a1[s1] = { 99 };
int a2[s2] = { 5, 6, 7, 8, 9 };
int m = m2a(a1, s1, a2, s2);
printf("%dn", m);
}
{
const int s1 = 5;
const int s2 = 1;
int a1[s1] = { 5, 6, 7, 8, 9 };
int a2[s2] = { 99 };
int m = m2a(a1, s1, a2, s2);
printf("%dn", m);
}
{
const int s1 = 5;
const int s2 = 5;
int a1[s1] = { 1,1,1,1,1 };
int a2[s2] = { 1,1,1,1,1 };
int m = m2a(a1, s1, a2, s2);
printf("%dn", m);
}
{
const int s1 = 5;
const int s2 = 1;
int a1[s1] = { 5, 6, 7, 8, 9 };
int a2[s2] = { 3 };
int m = m2a(a1, s1, a2, s2);
printf("%dn", m);
}
return 0;
}
修复了剩余的错误。脑死亡胜过"优雅"。如果你有3种情况,试图隐藏它是危险的。因此,环的身体也显示了这3种情况。。。
也许您可以更改:
if (A[ida] < B[idb])
收件人:
if (ida < m && A[ida] < B[idb])
和:
return (A[ida] < A[idb] ? A[ida] : B[idb]);
收件人:
return (ida < m && A[ida] < A[idb] ? A[ida] : B[idb]);
相关文章:
- 需要帮助设置在C++中使用的Potrace
- 在指针的帮助下,文本文件中单词的频率
- 计算每个节点的树高,帮助我解释这个代码解决方案
- 如何在Qbutton的帮助下更改Q对话框的宽度
- 需要帮助将结构数组传递给函数
- C++需要帮助从用户那里获得一个整数,并确保它在另外两个整数之间
- 当基类是依赖类型时,这是一个缺陷吗
- 需要帮助在 c++ 中将字符串转换为字符 ----错误 "const char *" 类型的值不能用于初始化 "char" 类型的实体
- 有人可以帮助我处理正则表达式吗?
- C++调用具有 *this 属性的单个帮助程序函数
- C++:需要帮助了解运算符重载错误
- 需要以下代码的帮助,下面的代码有什么问题
- CS1 项目帮助C++
- 用于检查值是否为其任何参数的帮助程序函数
- 需要有关此 if 语句的帮助
- 类型限定宏帮助程序
- CoreCLR 中的检测探查器 - 将帮助程序程序集加载到 dotnet 进程的方法
- 在这个函数中是有缺陷的,因为取消引用 null 是无效的,所以我想更改代码
- NS3 插槽混淆(需要帮助理解)
- 需要帮助为我的算法中的缺陷提供优雅的修复