如何使用二进制搜索java打印数组中的重复值



嗨,我正在创建一个程序,该程序在searchMark方法中有两个平行数组(studentNum&grades(。我也会提示用户输入他们想要查找的等级。然后,该程序使用二进制搜索来查找该值,然后检查是否有其他学生拥有该值。然后,所有学生的编号及其成绩都会打印在输出屏幕上。程序/代码将在数组中定位目标的第一个实例后立即结束,我已经包含了我的输出和输出应该是什么样子的图片。

// Binary Search
int startIndex = 0, endIndex = 0;
int middleIndex;
int shiftPlus = 0;
int shiftMinus = grade.length-1;
int midValue = 0;
while (startIndex <= endIndex) {

middleIndex = (startIndex+endIndex)/2;

if (grade[middleIndex] == target) {
midValue = grade[middleIndex];
System.out.println("student #" + student[middleIndex] 
+ " has a correct count of " + target);
break;
}
else if (grade[middleIndex] > target)
endIndex = middleIndex-1;

else if (grade[middleIndex] < target)
startIndex = middleIndex + 1;
}  

boolean aboveMid = true, belowMid = true; // for while loops to stop/start

while (shiftPlus <= midValue && aboveMid == true) {
shiftPlus += 1; // starts at 0 and moves 1 up each loop            
if(grade[shiftPlus] == target && shiftPlus <= midValue) 
{
System.out.println("student #" + student[shiftPlus] 
+ " has a correct count of " + target);
}
else
belowMid = false;          
}

while (shiftMinus >= midValue && belowMid == true) {
shiftMinus -= 1; // subtract one from end
if(grade[shiftMinus] == target && shiftMinus <= midValue) 
{
System.out.println("student #" + student[shiftMinus] 
+ " has a correct count of " + target);
} 
else
aboveMid = false;            
}
}

该代码的输出是当我输入除3以外的任何数字时:

你想搜索什么标记?6.构建成功(总时间:2秒(

但是,如果我输入数字"3"你想搜索什么标记?3.2号学生的正确计数为3学生#3的正确计数为3

二进制搜索是在java(Arrays.binarySearch(中构建的,自己编写是错误的。当然,除非这是家庭作业,而编写二进制搜索算法就是家庭作业。

请注意,二进制搜索要求对输入数组进行排序。对未排序的输入运行binsearch会产生垃圾。和中一样,没有错误,只是。。结果是错误的答案。这是二进制搜索的一个基本性质。

思考一下你的算法:假设所有学生都得了6分。很明显,目的是让您打印出所有学生。

您的代码将只打印在两个地方。这两个位置在for循环中,它用于循环X次,其中X是"target-shiftPlus"。您的代码并不完整(shiftPlus在任何地方都没有定义(,但很明显,如果"目标"发生变化,打印次数也会发生变化。这证明了这是没有意义的:如果你在寻找得分为7的学生,而他们的得分都为7,你会打印一个多或少一个,而不是你在寻找分数为6的学生,他们都得分为6?不,那不可能是对的。因此,"目标"首先不应该是循环计数的一部分,在设计该算法的过程中,你犯了错误。

这部分算法的目的是"环视"你的二进制搜索找到的索引,因为可能有不止一个学生的预期分数,如果超过1,他们将直接与你的"命中"相邻。

一个关键的线索是,在你到达那里之前,你不知道可能有多少点击,所以一个计数的for循环是正确的。也许while更合适?for也可以工作,但一些索引查找需要成为终止条件的一部分(在for内的两个;之间(。

假设分数为:[4,6,6,7,8],而您的binsearch恰好偶然发现了3个6分数中的第一个。换句话说,二进制搜索的结果是:在index=1处存在匹配。

你想首先"向下看"4(因此,相对于你找到的索引为-1:index=0(,在索引0(即4(处查找分数,意识到4不是6,并且不打印任何内容,此外,停止向下看。

然后你想"查找",从你自己的索引(index=1(开始,在该索引(6(处获取分数,意识到这实际上是目标索引,所以打印该学生,然后继续:在索引(index=2(上加1,然后重复算法。这个"点击"再次,打印另一个学生,增加索引,第三次点击,将索引增加到4,在索引4处获取分数(7(,现在失败了,所以不打印任何内容,也不会继续查看。然后,当没有任何进一步的索引可供查看时,你还需要在边缘情况下进行编程。假设输入是[4,6,6,6],你不希望程序以ArrayIndexOutOfBoundsException崩溃,因为你的算法一直在列表中走得更远,直到找到一个不是6的数字。

我不会把一个功能齐全的程序放在这里,因为这显然是家庭作业,目的是让你学习和理解java,而不是学习和理解CTRL/CMD+C和CTRL/CMD+V键的功能:(

假设您找到了要查找的项目,并且它在索引idx中,因此您可以在其边界等于arr[idx]时进行迭代

leftidx = idx-1;
while(arr[leftidx]==arr[idx]{
System.out.println(arr[leftidx]);
lefidx--;
}
rightidx = idx+1;
while(arr[rightidx]==arr[idx]{
System.out.println(arr[rightidx]);
rightidx--;
}

相关内容

  • 没有找到相关文章

最新更新