简体   繁体   中英

Binary search of sorted-by-column 2D array only searching first column

So I'm pretty new to programming, and I'm trying to apply a binary search algorithm to a two-dimensional array that is sorted by column. My program only correctly performs on the first column, so I think it is getting stuck in an infinite loop. The problem seems to be within the second else-if statement in my while loop, but I'm totally at a loss as to what the problem might be.

public static void main(String[] args) {
    // TODO Auto-generated method stub

    int[][] array = { {5, 8, 10, 6},
            {20, 10, 20, 15},
            {20, 15, 25, 20}, 
            {20, 20, 32, 25} };
    int query = 20;

    int search_status;
    search_status = count(array, query);
    System.out.println(query + " occurred " + search_status + " times");

}

public static int count(int[][]array, int query){
    int count = 0;
    int low = 0;
    int high = array.length - 1;
    for (int c = 0; c < array[0].length; c++) {
        while (low <= high) {
            int mid = low + (high - low) / 2;

            if (array[mid][c] > query) {
                high = mid - 1;
            }
            else if (array[mid][c] < query) {
                low = mid + 1;
            }
            else if (array[mid][c] == query) {
                count++;
                int up = -1;
                int down = 1;
                while ((mid + up >= 0) && (array[mid + up][c] == query)) {
                    up--;
                    count++;
                }
                while ((mid + down <= array.length - 1) && (array[mid + down][c] == query)) {
                    down++;
                    count++;
                }
                return count;
            }
        }
    }
    return - 1;
}

}

Try this approach of pushing the columns into rows first:

public static void main(String[] args) {
    // TODO Auto-generated method stub

    int[][] array = { {5, 8, 10, 6},
            {20, 10, 20, 15},
            {20, 15, 25, 20}, 
            {20, 20, 32, 25} };
    int query = 20;

    int search_status = 0;

    for (int c = 0; c < array.length; c++)
        search_status += count(array, query, c);

    System.out.println(query + " occurred " + search_status + " times");

}

public static int count(int[][]array, int query, int row){
    int[] column = new int[array.length];
    int count = 0;
    int low = 0;
    int high = column.length - 1;

    for (int i = 0; i < array[row].length; i++)
        column[i] = array[i][row];

    while (low <= high) {
        int mid = low + (high - low) / 2;

        if (column[mid] > query) {
            high = mid - 1;
        }
        else if (column[mid] < query) {
            low = mid + 1;
        }
        else if (column[mid] == query) {
            int mover = -1;
            int counted = 1;

            // Go all the way down
            while ((mid + mover >= 0) && (column[mid + mover] == query))
            {
                mover--;
                counted++;
            }

            mover+=counted+1;
            count+=counted;

            while ((mid + mover <= column.length - 1) && (column[mid + mover] == query))
            {
                mover++;
                count++;
            }

            return count;
        }
    }

    return 0;
}

EDIT : Slightly better implementation so as not to double-count.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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