繁体   English   中英

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

[英]How do I print repeated values from an array using binary search 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 循环内,它 for 循环 X 次,其中 X 是“目标 - shiftPlus”。 您的代码不完整(shiftPlus 未在任何地方定义),但很明显,如果“目标”发生变化,打印数量也会发生变化。 这证明这是没有意义的:如果您正在寻找得分为 7 的学生,并且他们的得分都为 7,那么您将多打印一个或少打印一个,而如果您正在寻找得分为 6 的情况,那么他们将打印都得了6分? 不,这不可能是对的。 因此,“目标”一开始就不应该是循环计数的一部分,在设计此算法的过程中,您走错了路。

算法的这一部分的重点是“环顾”二分搜索找到的索引,因为可能有多个学生达到预期分数,如果超过 1,他们将与您的分数紧邻'打'。

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

假设分数是:[4,6,6,6,7,8],并且您的 binsearch 碰巧偶然发现了 3 6分数中的第一个 换句话说,二分查找的结果是:在 index = 1 处有匹配项。

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

然后你想'查找',从你自己的索引(索引 = 1)开始,在那个索引( 6 )处获取分数,意识到这实际上是目标索引,所以打印那个学生然后继续:加 1到您的索引(现在索引 = 2)并重复该算法。 这再次“命中”,打印另一个学生,增加索引,第三次命中,将索引增加到 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--;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM