簡體   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