The program I have is supposed to divide the matrix into four quadrants continuously until it finds the given value. With the current program it runs forever. How do I get it to post the number I search for?
public static void DivideAndConquerSearch(int target, int fromRow, int toRow, int fromCol, int toCol, int[][] matrix, int comparison_counter) {
boolean found = false;
while (!found) {
int i = fromRow + (toRow - fromRow) / 2;
int j = fromCol + (toCol - fromCol) / 2;
if (matrix[i][j] == target) {
found = true;
} else if (matrix[i][j] < target) {
if (i + 1 <= toRow) {
found = false;
DivideAndConquerSearch(target, i + 1, toRow, fromCol, toCol, matrix, comparison_counter);
} else if (j - 1 >= fromCol) {
found = false;
DivideAndConquerSearch(target, fromRow, toRow, fromCol, j - 1, matrix, comparison_counter);
}
}
comparison_counter++;
}
if (found == true) {
System.out.println(target + " found in " + comparison_counter + " comparisons using recursive search");
} else {
System.out.println(target + " NOT found in " + comparison_counter + " comparisons using recursive search");
}
}
I wrote up something that simply searches all over the array (brute-force kinds) using a recursive approach. It splits the 2D array into 4 quadrants and search NW, NE, SW, SE. I used an OR condition to check if it is found in any of the quadrants. So, if number is found in NW, it won't search the rest (yay!). Let me know if you have any questions. The code isn't the prettiest or the most optimized, and I have kinda chosen to leave it that way so that you can understand what I am doing a little better. The full class, including a (very basic) test...
public class Divide_Conquer_2dArr {
private static boolean divideAndConquer(int[][] arr, int target) {
/* IDEA */
// NORTH_WEST [Kanye West joke(?)]
// need to search row-wise from [0,row-1], col-wise from [0, col-1]
// NORTH_EAST
// need to search row-wise from [0,row-1], col-wise from [col, maxCol]
// SOUTH_WEST
// need to search row-wise from [row, maxRow], col-wise from [0, col-1]
// SOUTH_EAST
// need to search row-wise from [row, maxRow], col-wise from [col, maxCol]
return divideAndConquerHelper(arr, target, 0, arr[0].length-1, 0, arr.length-1);
}
private static boolean divideAndConquerHelper(int[][] arr, int target, int minCol,
int maxCol, int minRow, int maxRow) {
// print relevant stuff
printArr(arr, minCol, maxCol, minRow, maxRow);
if(minCol == maxCol || minRow == maxRow) {
if(minCol == maxCol) {
for(int i = minRow ; i <= maxRow ; i++)
if(arr[i][minCol] == target) {
System.out.println("Found!");
return true;
}
}
else if(minRow == maxRow) {
for(int i = minCol ; i <= maxCol ; i++)
if(arr[minRow][i] == target) {
System.out.println("Found!");
return true;
}
}
return false;
}
int midRow = (maxRow + minRow)/2;
int midCol = (maxCol + minCol)/2;
return
// north-west quadrant
divideAndConquerHelper(arr, target, minCol, midCol, minRow, midRow)
||
// north-east quadrant
divideAndConquerHelper(arr, target, midCol+1, maxCol, minRow, midRow)
||
// south-west quadrant
divideAndConquerHelper(arr, target, minCol, midCol, midRow+1, maxRow)
||
// south-east quadrant
divideAndConquerHelper(arr, target, midCol+1, maxCol, midRow+1, maxRow);
}
// prints arr[minRow..maxRow][minCol..maxCol] inclusive
private static void printArr(int[][] arr, int minCol,
int maxCol, int minRow, int maxRow) {
for(int i = minRow ; i <= maxRow ; i++ ) {
for(int j = minCol ; j <= maxCol ; j++) {
System.out.print(arr[i][j] + "\t");
}
System.out.println();
}
System.out.println("==================================");
}
public static void main(String[] args) {
int[][] arr = new int[][]
{
{1,2,3,4},
{6,7,8,9},
{11,12,13,14},
{16,17,18,19},
{21,22,23,24}
};
boolean retVal = divideAndConquer(arr, 12);
if(!retVal)
System.out.println("Not found :(");
}
}
Related
My problem statement is this -
Find the count of numbers in a sorted array that are less than a given number, and this should be done efficiently with respect to time. I wrote a program using binary search that gets the count but time complexity wise it's failing. Need help in achieving this.
import java.util.Arrays;
public class SortedSearch {
public static int countNumbers(int[] sortedArray, int lessThan) {
if(sortedArray.length ==1 || sortedArray.length == 0) {
return singleElement(sortedArray, lessThan);
}
else {
return binarySearch(sortedArray, lessThan);
}
}
public static int singleElement(int[] sortedArray, int searchVal) {
if(sortedArray.length == 0) {
return 0;
}
if(sortedArray[0] < searchVal) {
return 1;
}
return 0;
}
private static int binarySearch(int[] sortedArray, int searchVal) {
int low = 0;
int high = (sortedArray.length)-1;
int mid = (low + high)/2;
if((sortedArray.length == 0) || (sortedArray[0] > searchVal)) {
return 0;
}
if(sortedArray[high] < searchVal) {
return sortedArray.length;
}
if(sortedArray[high] == searchVal) {
return sortedArray.length-1;
}
if(sortedArray[mid] < searchVal) {
int newLow = low;
int newHigh = calculateNewHigh(sortedArray, newLow, 0, searchVal);
int[] newArray = Arrays.copyOfRange(sortedArray, newLow, newHigh+1);
return newArray.length;
}
else {
int newLow = low;
int newHigh = mid;
int[] newArray = Arrays.copyOfRange(sortedArray, newLow, newHigh+1);
return binarySearch(newArray, searchVal);
}
}
private static int calculateNewHigh(int[] sortedArray, int low, int previousHigh, int searchVal) {
int newHigh = previousHigh + (sortedArray.length-low)/2;
if(sortedArray[newHigh] < searchVal) {
newHigh = calculateNewHigh(sortedArray, newHigh, newHigh, searchVal);
}
if(sortedArray[newHigh] == searchVal) {
newHigh--;
}
if(sortedArray[newHigh] > searchVal) {
newHigh--;
}
return newHigh;
}
public static void main(String[] args) {
System.out.println(SortedSearch.countNumbers(new int[] { 1, 3, 5, 7 }, 4));
}
}
Since you're using Arrays anyway, way not use the Arrays.binarySearch(int[] a, int key) method, instead of attempting to write your own?
public static int countNumbers(int[] sortedArray, int lessThan) {
int idx = Arrays.binarySearch(sortedArray, lessThan);
if (idx < 0)
return -idx - 1; // insertion point
while (idx > 0 && sortedArray[idx - 1] == lessThan)
idx--;
return idx; // index of first element with given value
}
The while loop1 is necessary because the javadoc says:
If the array contains multiple elements with the specified value, there is no guarantee which one will be found.
1) This loop is not optimal if e.g. all values are the same, see e.g. Finding multiple entries with binary search
I have a program that sorts randomly generated numbers from least to greatest or greatest to least depending on the users choice. 2 problems are occurring.
When the user does Insertion Sorting with Descending, the randomly generated numbers and sorting numbers output like this for example:
Randomly Generated Numbers:
89 90 2 830 399
After sorting using the Insertion Sort, Using Descending Order, the array is:
89 90 2 830 399
It's weird because my other methods are EXACTLY the same, and they work fine, but for some reason this doesn't work.
Here is my code:
import javax.swing.*;
import java.lang.reflect.Array;
import java.util.Random;
public class RoutineSorter {
private static int[] generateRandomArray(int size, int randomMax) {
int[] array = new int[size];
Random randomGenerator = new Random();
for (int i = 0; i < size; i++) {
array[i] = randomGenerator.nextInt(randomMax);
}
return array;
}
public static void main(String[] args) {
int MethodChoice = Integer.parseInt(JOptionPane.showInputDialog("What method would you like to use to sort the random numbers" + "\n" + "1 - Selection Sort" + "\n" + "2 - Bubble Sort" + "\n" + "3 - Insertion Sort" + "\n" + "4 - Quick Sort"));
int iTotalCount = Integer.parseInt(JOptionPane.showInputDialog("What is the total number of integers?"));
int SortOrder = Integer.parseInt(JOptionPane.showInputDialog("1 - Ascending, " + "2 - Descending"));
int[] array = generateRandomArray(iTotalCount, 1001);
System.out.println("Randomly Generated number list: ");
for (int i: array) {
System.out.print(i + " ");
}
System.out.println("\n---------------------------------");
if (MethodChoice == 1) {
if (SortOrder == 2) {
selectionSortReverse(array);
System.out.println("After sorting using the Selection Sort, " + "Using Descending Order" + " " + "the array is: ");
} else if (SortOrder == 1) {
selectionSort(array);
System.out.println("After sorting using the Selection Sort," + " the array is:");
}
} else if (MethodChoice == 2) {
if (SortOrder == 2) {
bubbleSortReverse(array);
System.out.println("After sorting using the Bubble Sort, " + "Using Descending Order" + " " + "the array is: ");
} else if (SortOrder == 1) {
bubbleSort(array);
System.out.println("After sorting using the Bubble Sort," + " the array is:");
}
} else if (MethodChoice == 3) {
if (SortOrder == 2) {
insertionSortReverse(array);
System.out.println("After sorting using the Insertion Sort, " + "Using Descending Order" + " " + "the array is: ");
} else if (SortOrder == 1) {
insertionSort(array);
System.out.println("After sorting using the Insertion Sort," + " the array is:");
} else if (MethodChoice == 4) {
if (SortOrder == 2) {
}
}
for (int i: array) {
System.out.print(i + " ");
}
}
}
public static void quickSort(int data[], int low, int high) {
int partitionLoc;
if (low < high) {
partitionLoc = partition(data, low, high);
quickSort(data, low, partitionLoc - 1);
quickSort(data, partitionLoc + 1, high);
}
}
public static void quickSortReverse(int data[], int low, int high) {
int partitionLoc;
if (low > high) {
partitionLoc = partition(data, low, high);
quickSort(data, low, partitionLoc - 1);
quickSort(data, partitionLoc + 1, high);
}
}
public static int partition(int data2[], int left, int right) {
boolean moveLeft = true;
int separator = data2[left];
while (left < right) {
if (moveLeft == true) {
while ((data2[right] >= separator) && (left < right)) {
right--;
}
data2[left] = data2[right];
moveLeft = false;
} else {
while ((data2[left] <= separator) && (left < right)) {
left++;
}
data2[right] = data2[left];
moveLeft = true;
}
}
data2[left] = separator;
return left;
}
public static void bubbleSort(int data[]) {
//Loop to control number of passes
for (int pass = 1; pass < data.length; pass++) {
//Loop to control # of comparisons for length of array-1
for (int element = 0; element < data.length - 1; element++) {
//compare side-by-side elements and swap them if
//first element is greater than second element
if (data[element] > data[element + 1]) {
swap(data, element, element + 1); //call swap method
}
}
}
}
public static void bubbleSortReverse(int data[]) {
//Loop to control number of passes
for (int pass = 1; pass < data.length; pass++) {
//Loop to control # of comparisons for length of array-1
for (int element = 0; element < data.length - 1; element++) {
//compare side-by-side elements and swap them if
//first element is greater than second element
if (data[element] < data[element + 1]) {
swap(data, element, element + 1); //call swap method
}
}
}
}
public static void swapBubble(int array2[], int first, int second) {
int hold = array2[first];
array2[first] = array2[second];
array2[second] = hold;
}
public static void insertionSort(int data[]) {
int insert;
for (int next = 1; next < data.length; next++) {
insert = data[next];
int moveItem = next;
while (moveItem > 0 && data[moveItem - 1] > insert) {
data[moveItem] = data[moveItem - 1];
moveItem--;
}
data[moveItem] = insert;
}
}
public static void insertionSortReverse(int data[]) {
int insert;
for (int next = 1; next < data.length; next++) {
insert = data[next];
int moveItem = next;
while (moveItem < 0 && data[moveItem - 1] < insert) {
data[moveItem] = data[moveItem - 1];
moveItem--;
}
data[moveItem] = insert;
}
}
public static void selectionSort(int data[]) {
int smallest;
for (int i = 0; i < data.length - 1; i++) {
smallest = i;
//see if there is a smaller number further in the array
for (int index = i + 1; index < data.length; index++) {
if (data[index] < data[smallest]) {
swap(data, smallest, index);
}
}
}
}
public static void selectionSortReverse(int data[]) {
int smallest;
for (int i = 0; i < data.length - 1; i++) {
smallest = i;
//see if there is a smaller number further in the array
for (int index = i + 1; index < data.length; index++) {
if (data[index] > data[smallest]) {
swap(data, smallest, index);
}
}
}
}
public static void swap(int array2[], int first, int second) {
int hold = array2[first];
array2[first] = array2[second];
array2[second] = hold;
}
}
In the method insertionSortReverse() there is the mistake at the beginning of the while loop:
while (moveItem < 0 &&
It should be
while (moveItem > 0 &&
I suppose...
I fixed it. The problem was my insertionSortReverse() subroutine, one of the signs was the wrong way, so I put it to the opposite.
BEFORE
public static void insertionSortReverse(int data[]) {
int insert;
for (int next = 1; next < data.length; next++) {
insert = data[next];
int moveItem = next;
while (moveItem < 0 && data[moveItem - 1] < insert) {
data[moveItem] = data[moveItem - 1];
moveItem--;
}
data[moveItem] = insert;
}
}
AFTER
public static void insertionSortReverse(int data[]) {
int insert;
for (int next = 1; next < data.length; next++) {
insert = data[next];
int moveItem = next;
while (moveItem > 0 && data[moveItem - 1] < insert) {
data[moveItem] = data[moveItem - 1];
moveItem--;
}
data[moveItem] = insert;
}
}
I am trying to perfrom a ternary search on a array of strings. I have got most of code down and I think I am going on the right track but can't seem to get any results other then -1. Below is the code that I have genearated thus far. I know the problem is in the search algorithm. I do not want to use any built is as I am learning.
public static void main(String[] args) {
//declare a string array with initial size
String[] songs = {"Ace", "Space", "Diamond"};
System.out.println("\nTest binary (String):");
System.out.println(search(songs,"Ace"));
}
public static int search(String[] x, String target) {
int start=0, end=x.length;
while (start > end) {
int midpoint1 = start+(end - start)/3;
int midpoint2 = start +2*(end-start)/3;
if ( target.compareTo(x[midpoint1]) == 0 )
return midpoint1;
else if ( target.compareTo(x[midpoint2]) == 0 )
return midpoint2;
else if ( target.compareTo(x[midpoint1]) < 0 )
return end = midpoint1-1;
else if ( target.compareTo(x[midpoint2]) > 0 )
return start = midpoint2+1;
}
return -1;
}
You never get into the loop.
int start=0, end=x.length;
while (start > end)
You're while statement is wrong, it should contain start < end. I recomend learning the debug settings that are on most IDEs because if you're going to stick around it makes it so much easier to view the states of vars.
Try this corrected version, additionally to the bug identified by the Thomas and user2789574, you also have a bug in the recursion:
public static void main(String[] args) {
//declare a string array with initial size
String[] songs = {"Ace", "Space", "Diamond"};
System.out.println("\nTest binary (String):");
System.out.println(search(songs, "Ace", 0, 3));
}
public static int search(String[] x, String target, int start, int end) {
if (start < end) {
int midpoint1 = start + (end - start) / 3;
int midpoint2 = start + 2 * (end - start) / 3;
if (target.compareTo(x[midpoint1]) == 0) {
return midpoint1;
} else if (target.compareTo(x[midpoint2]) == 0) {
return midpoint2;
} else if (x[midpoint1].compareTo(x[midpoint2]) < 0) {
return search(x, target, midpoint1, end);
} else {
return search(x, target, start, midpoint2);
}
}
return -1;
}
end = x.length,will always return numeric value greater than zero for not null string and it's comparison with start =0 , it will never enter into the loop.
I am not sure if its still relevant now, but here is the ternary search done with loops in java(assuming that the array is pre-sorted):
public static int ternSearch(String[] x, String target) {
if((target.toLowerCase()).compareTo(x[0].toLowerCase()) == 0)
{
return 0;
}
if((target.toLowerCase()).compareTo(x[x.length - 1].toLowerCase()) == 0)
{
return x.length-1;
}
int mid1 = (int) Math.ceil( x.length/3);
if((target.toLowerCase()).compareTo(x[mid1].toLowerCase()) == 0)
{
return mid1;
}
int mid2 = (int) Math.ceil( x.length*2/3);
if((target.toLowerCase()).compareTo(x[mid2].toLowerCase()) == 0)
{
return mid2;
}
if((target.toLowerCase()).compareTo(x[0].toLowerCase()) > 0&& (target.toLowerCase()).compareTo(x[mid1].toLowerCase()) < 0)
{
for (int i = 1; i < mid1; i++)
{
if((target.toLowerCase()).compareTo(x[i].toLowerCase()) == 0)
{
return i;
}
}
}
else if((target.toLowerCase()).compareTo(x[mid1].toLowerCase()) > 0&& (target.toLowerCase()).compareTo(x[mid2].toLowerCase()) < 0)
{
for (int i = mid1+1; i < mid2; i++)
{
if((target.toLowerCase()).compareTo(x[i].toLowerCase()) == 0)
{
return i;
}
}
}
else if((target.toLowerCase()).compareTo(x[mid2].toLowerCase()) > 0&& (target.toLowerCase()).compareTo(x[x.length-1].toLowerCase()) < 0)
{
for (int i = mid2+1; i < x.length-2; i++)
{
if((target.toLowerCase()).compareTo(x[i].toLowerCase()) == 0)
{
return i;
}
}
}
return -1;
}
I'm trying to write a backtracking code that will find the number of solutions in a NQueens problem. But I am getting stack overflows when I try to mark the diagonal grids where it is not safe to place a queen.
int dim;
private void recurseMark(int row, int col, boolean[][] board, boolean val) {
if(row >= dim || col >= dim || row < 0 || col < 0) return;
if(board[row][col]) return;
System.out.println("Row " + row + " Col " + col);
board[row][col] = val;
recurseMark(row+1, col-1, board, val);
recurseMark(row+1, col+1, board, val);
recurseMark(row-1, col+1, board, val);
recurseMark(row-1, col-1, board, val);
}
private void mark(int i, int k, boolean[][] board, boolean val) {
for(int j = 0; j < dim; j++) {
board[i][j] = val;
}
for(int j = 0; j < dim; j++) {
board[j][k] = val;
}
}
private int countQueens(int i, boolean[][] board) {
int count = 0;
if(i == dim) return 1;
for(int k = 0; k < dim; k++) {
if(!board[i][k]) {
board[i][k] = true;
mark(i, k, board, true);
System.out.println("Giving " + i + " " + k);
recurseMark(i, k, board, true);
count += countQueens(i+1, board);
recurseMark(i, k, board, false);
mark(i, k, board, false);
}
}
return count;
}
public int totalNQueens(int n) {
dim = n;
boolean[][] board = new boolean[n][n];
return countQueens(0, board);
}
public static void main(String[] args) {
NQueens nq = new NQueens();
System.out.println(nq.totalNQueens(2));
}
Any idea why it's overflowing for a small value of N?
Because your method recurses infinitely.
If the board is 8x8, then for example recurseMark(1, 1, board, false) calls recurseMark(2, 2, board, false) which calls recurseMark(1, 1, board, false) which calls recurseMark(2, 2, board, false) which calls recurseMark(1, 1, board, false) which ...
The problem is when recurseMark is called with false. Here is a correct recurseMark():
private void recurseMark(int row, int col, Boolean[][] board, Boolean val) {
if(row >= dim || col >= dim || row < 0 || col < 0) return;
if(board[row][col] != null) return;
System.out.println("Row " + row + " Col " + col);
board[row][col] = val;
recurseMark(row+1, col-1, board, val);
recurseMark(row+1, col+1, board, val);
recurseMark(row-1, col+1, board, val);
recurseMark(row-1, col-1, board, val);
}
What we have done here is to switch to a Boolean class rather than primitive boolean, and use the null case to represent "square not visited yet". As it was the "square not visited" state was "false".
Can I get some help please? I have tried many methods to get this to work i got the array sorted and to print but after that my binary search function doesnt want to run and give me right results. It always gives me -1. Any help?
public class BinarySearch {
public static final int NOT_FOUND = -1;
public static int binarySearch(double[] a, double key) {
int low = 0;
int high = a.length -1;
int mid;
while (low<=high) {
mid = (low+high) /2;
if (mid > key)
high = mid -1;
else if (mid < key)
low = mid +1;
else
return mid;
}
return NOT_FOUND;
}
public static void main(String[] args) {
double key = 10.5, index;
double a[] ={10,5,4,10.5,30.5};
int i;
int l = a.length;
int j;
System.out.println("The array currently looks like");
for (i=0; i<a.length; i++)
System.out.println(a[i]);
System.out.println("The array after sorting looks like");
for (j=1; j < l; j++) {
for (i=0; i < l-j; i++) {
if (a[i] > a[i+1]) {
double temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
}
}
}
for (i=0;i < l;i++) {
System.out.println(a[i]);
}
System.out.println("Found " + key + " at " + binarySearch(double a[], key));
}
}
you are not actually comparing with the array values. in
while (low <= high) {
mid = (low + high) / 2;
if (mid > key) {
high = mid - 1;
} else if (mid < key) {
low = mid + 1;
} else {
return mid;
}
}
Instead use this section
while (low <= high) {
mid = (low + high) / 2;
if (a[mid] > key) {
high = mid - 1;
} else if (a[mid] < key) {
low = mid + 1;
} else {
return mid;
}
}
You were correct to find the indexes, but what you were doing is that you were just comparing index number with your key, which is obviously incorrect. When you write a[mid] you will actually compare your key with the number which is at index mid.
Also the last line of code is giving compile error, it should be
System.out.println("Found " + key + " at " + binarySearch(a, key));
Here
if (mid > key)
high = mid -1;
else if (mid < key)
low = mid +1;
else
return mid;
You're comparing index to a value (key) in array. You should instead compare it to a[mid]
And,
System.out.println("Found " + key + " at " + binarySearch(double a[], key));
Should be
System.out.println("Found " + key + " at " + binarySearch(a, key));
public static double binarySearch(double[] a, double key) {
if (a.length == 0) {
return -1;
}
int low = 0;
int high = a.length-1;
while(low <= high) {
int middle = (low+high) /2;
if (b> a[middle]){
low = middle +1;
} else if (b< a[middle]){
high = middle -1;
} else { // The element has been found
return a[middle];
}
}
return -1;
}
int binarySearch(int list[], int lowIndex, int highIndex, int find)
{
if (highIndex>=lowIndex)
{
int mid = lowIndex + (highIndex - lowIndex)/2;
// If the element is present at the
// middle itself
if (list[mid] == find)
return mid;
// If element is smaller than mid, then
// it can only be present in left subarray
if (list[mid] > find)
return binarySearch(list, lowIndex, mid-1, find);
// Else the element can only be present
// in right subarray
return binarySearch(list, mid+1, highIndex, find);
}
// We reach here when element is not present
// in array
return -1;
}
I somehow find the iterative version not quite easy to read, recursion makes it nice and easy :-)
public class BinarySearch {
private static int binarySearchMain(int key, int[] arr, int start, int end) {
int middle = (end-start+1)/2 + start; //get index of the middle element of a particular array portion
if (arr[middle] == key) {
return middle;
}
if (key < arr[middle] && middle > 0) {
return binarySearchMain(key, arr, start, middle-1); //recurse lower half
}
if (key > arr[middle] && middle < arr.length-1) {
return binarySearchMain(key, arr, middle+1, end); //recurse higher half
}
return Integer.MAX_VALUE;
}
public static int binarySearch(int key, int[] arr) { //entry point here
return binarySearchMain(key, arr, 0, arr.length-1);
}
}
Here is a solution without heap. The same thing can be done in an array.
If we need to find 'k' largest numbers, we take an array of size 'k' populated with first k items from the main data source. Now, keep on reading an item, and place it in the result array, if it has a place.
public static void largestkNumbers() {
int k = 4; // find 4 largest numbers
int[] arr = {4,90,7,10,-5,34,98,1,2};
int[] result = new int[k];
//initial formation of elems
for (int i = 0; i < k; ++i) {
result[i] = arr[i];
}
Arrays.sort(result);
for ( int i = k; i < arr.length; ++i ) {
int index = binarySearch(result, arr[i]);
if (index > 0) {
// insert arr[i] at result[index] and remove result[0]
insertInBetweenArray(result, index, arr[i]);
}
}
}
public static void insertInBetweenArray(int[] arr, int index, int num) {
// insert num at arr[index] and remove arr[0]
for ( int i = 0 ; i < index; ++i ) {
arr[i] = arr[i+1];
}
arr[index-1] = num;
}
public static int binarySearch(int[] arr, int num) {
int lo = 0;
int hi = arr.length - 1;
int mid = -1;
while( lo <= hi ) {
mid = (lo+hi)/2;
if ( arr[mid] > num ) {
hi = mid-1;
} else if ( arr[mid] < num ) {
lo = mid+1;
} else {
return mid;
}
}
return mid;
}
int BinSearch(int[] array, int size, int value)
{
if(size == 0) return -1;
if(array[size-1] == value) return size-1;
if(array[0] == value) return 0;
if(size % 2 == 0) {
if(array[size-1] == value) return size-1;
BinSearch(array,size-1,value);
}
else
{
if(array[size/2] == value) return (size/2);
else if(array[size/2] > value) return BinSearch(array, (size/2)+1, value);
else if(array[size/2] < value) return (size/2)+BinSearch(array+size/2, size/2, value);
}
}
or
Binary Search in Array
/**
* Find whether 67 is a prime no
* Domain consists 25 of prime numbers
* Binary Search
*/
int primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97};
int min = 0,
mid,
max = primes.length,
key = 67,
count= 0;
boolean isFound = false;
while (!isFound) {
if (count < 6) {
mid = (min + max) / 2;
if (primes[mid] == key) {
isFound = true;
System.out.println("Found prime at: " + mid);
} else if (primes[mid] < key) {
min = mid + 1;
isFound = false;
} else if (primes[mid] > key) {
max = mid - 1;
isFound = false;
}
count++;
} else {
System.out.println("No such number");
isFound = true;
}
}
/**
HOPE YOU LIKE IT
A.K.A Binary Search
Take number array of 10 elements, input a number a check whether the number
is present:
**/
package array;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
class BinaryS
{
public static void main(String args[]) throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter a number: ");
int n=Integer.parseInt(br.readLine());
int a[]={10,20,30,40,50,60,70,80,90,100};
int upper=a.length-1,lower=0,mid;
boolean found=false;
int pos=0;
while(lower<=upper)
{
mid=(upper+lower)/2;
if(n<a[mid])upper=mid-1;
else if(n>a[mid])lower=mid+1;
else
{
found=true;
pos=mid;
break;
}
}
if(found)System.out.println(n+" found at index "+pos);
else System.out.println(n+" not found in array");
}
}
Well I know I am posting this answer much later.
But according to me its always better to check boundary condition at first.
That will make your algorithm more efficient.
public static int binarySearch(int[] array, int element){
if(array == null || array.length == 0){ // validate array
return -1;
}else if(element<array[0] || element > array[array.length-1]){ // validate value our of range that to be search
return -1;
}else if(element == array[0]){ // if element present at very first element of array
return 0;
}else if(element == array[array.length-1]){ // if element present at very last element of array
return array.length-1;
}
int start = 0;
int end = array.length-1;
while (start<=end){
int midIndex = start + ((end-start)/2); // calculate midIndex
if(element < array[midIndex]){ // focus on left side of midIndex
end = midIndex-1;
}else if(element > array[midIndex]){// focus on right side of midIndex
start = midIndex+1;
}else {
return midIndex; // You are in luck :)
}
}
return -1; // better luck next time :(
}
static int binarySearchAlgorithm() {
// Array should be in sorted order. Mandatory requirement
int[] a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int lowIndex = 0;
int valueToFind = 8;
int highIndex = a.length - 1;
while (lowIndex <= highIndex) {
//Finding the midIndex;
int midIndex = (highIndex + lowIndex) / 2;
// Checking if midIndex value of array contains the value to be find.
if (a[midIndex] == valueToFind) {
return midIndex;
}
// Checking the mid Index value is less than the value to be find.
else if (a[midIndex] < valueToFind) {
// If Yes, changing the lowIndex value to midIndex value + 1;
lowIndex = midIndex + 1;
} else if (a[midIndex] > valueToFind) {
// If Yes, changing the highIndex value to midIndex value - 1;
highIndex = midIndex - 1;
} else {
return -1;
}
}
return -1;
}