【问题标题】:How do I print repeated values from an array using binary search java如何使用二进制搜索java从数组中打印重复值
【发布时间】:2020-10-07 13:15:41
【问题描述】:

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

       // 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

【问题讨论】:

  • 很遗憾,我一直无法让它搜索具有相同分数的其他学生。 不幸的是,这不是我们可以帮助解决的问题描述。请参阅minimal reproducible example 并相应地增强您的问题。
  • 现在怎么样了?我对这个平台很陌生
  • 请不要使用截图。这些应该是你最后的手段。确保您的问题包含您正在使用的输入,以及作为 text 的输出。
  • 从现在开始当我有问题时会这样做。谢谢

标签: java arrays matrix netbeans


【解决方案1】:

二分查找是java内置的(Arrays.binarySearch),自己写是错误的。当然,除非这是家庭作业,而编写二进制搜索算法是家庭作业。

请注意,二分搜索要求您的输入数组已排序。对未排序的输入运行 binsearch 会产生垃圾。如中,没有错误,只是..错误的答案结果。这是二分搜索的基本属性。

想一想你的算法:假设所有学生得了 6 分。那么很明显,您的意图是打印出所有学生。

您的代码只会在两个地方打印。这两个地方在一个 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 相对于您找到的索引:索引 = 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 键 :)

【讨论】:

  • 嗨,谢谢你的帮助,我让它再次工作,但只有当我输入目标值 3 时。当输入的目标值是 3 时,它会打印两个获得分数 3 的学生。但是,如果我说输入 6,它只是说构建完成。顺便说一句,谢谢你没有发布我宁愿挣扎然后得到答案的代码。无论如何,如果你能提供一些额外的指导和批评,我更新了代码,那就太好了!
  • @RayaanKhan 你的输入排序了吗?
【解决方案2】:

假设您找到了您正在寻找的项目,并且它位于索引 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--;
}

【讨论】:

    猜你喜欢
    • 2021-05-16
    • 2020-11-13
    • 1970-01-01
    • 2012-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-07
    • 1970-01-01
    相关资源
    最近更新 更多