我已经实现了一个低效的线性搜索版本但我在测试算法时遇到了问题,出于某种原因,每10个不同的测试,2-3会产生无效的结果。我正在测试这个vs .net Contains,即:
Test 1:
LinearSearch(new int[] {1,2,3,4,5}, 4) : true
(new int[] {1,2,3,4,5}.Contains(4) : true
Test 2:
LinearSearch(new int[] {5,6,7,8,9}, 6) : true
(new int[] {5,6,7,8,9}.Contains(6) : true
Test 2:
LinearSearch(new int[] {10,11,12,13,14}, 13) : false
(new int[] {10,11,12,13,14}.Contains(13) : true
虽然这只是一个例子而不是我如何测试任何东西。主要是为了演示我测试算法的顺序。
继续这里是我的实现(不是完整版本,只是我遇到问题的部分):
public static int Search(T[] elements, T item)
{
int result = -1;
int length = elements.Length;
int half = elements.Length / 2;
bool upperBoundG = Comparer<T>.Default.Compare(elements[elements.Length - 1], item) > 0;
bool upperBoundQ = Comparer<T>.Default.Compare(elements[elements.Length - 1], item) == 0;
if (!upperBoundG)
return -1;
else if (upperBoundQ)
return elements.Length - 1;
else
{
for (int j = 0, i = half - 1; j < half && i < length; j++, i++)
{
result = elements[j].Equals(item) ? j : elements[i].Equals(item) ? i : -1;
if (result != -1) break;
}
return result;
}
}
这不是整个算法,这是导致问题的搜索方法,特别是在循环内。
该算法基于将键设置为-1的标准线性搜索,循环遍历集合,如果找到,则将键设置为i并返回i else -1,但不是这样做我选择的旧方式将数组的最后一个元素与我们正在搜索的元素进行比较,原因是我想避免在项目较大时搜索错误的数组,或者如果它的等于设置了密钥(length - 1并在那里结束。在循环中,我通过在同一循环中迭代两次来分割搜索方法,其中第一次迭代是从0-mid开始,第二次是从中间开始(减去最后一项)。
现在说明已经结束了,我想指出错误肯定在这里:
result = collection[j].Equals(item) ? j : collection[i].Equals(item) ? i : -1;
虽然我并不是100%确定这是代码的一部分给我这样的结果,所以如果你们真的没有看到任何错误并需要更多的东西,我会添加更多的例子。
PS:这不是家庭作业或类似的东西,基本上只是为了学习目的。我知道很多人以前都试过这个问题,你们中的一些人可能会觉得这个问题毫无意义但是我很好奇并且想知道我是否能想出一个有效的线性搜索,至少和Contains一样快(如果可能的话)。