Binary Search implementation via java - java

Please see the below java source code for binary search implementation
public class Main {
public static void main(String[] args) {
int[] x = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
int y = binarySearch(x, 11);
System.out.println(y);
}
public static int binarySearch(int[] arr, int value) {
int searchedIndex = -1;
int first = 0;
int last = arr.length - 1;
int mid;
while (first <= last) {
mid = (first + last) / 2;
if (arr[mid] == value) {
searchedIndex = mid;
break;
} else {
if (value < arr[mid]) {
last = mid - 1;
} else {
first = mid + 1;
}
}
}
return searchedIndex;
}
}
int last = arr.length - 1 is -1 compulsory or not. I feel that code works fine either last = arr.length - 1. If its compulsory please explain why.

Arrays already have a method binarySearch you can just use :
int[] x = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
int r = Arrays.binarySearch(x, 11);

The -1 is needed for one very specific case: when you search for a value that is larger than the largest value in the array. For example, calling your function with
int y = binarySearch(x, 50);
will throw an ArrayOutOfBounds exception. That's because mid will eventually be equal to last, and without the -1, last is past the end of the array.

Related

How can I implement JUnit testing into this program for a binary search?

How can I implement JUnit testing into this program for a binary search, i am quite overwhelmed by this task because I am really unfamiliar with JUnit and also I have all these packages and path that you see in code that I need to use.
I have already tried implementing Testing for just a normal Java class made by me but that did not work either, it would be great if someone could also explain me the syntax of some tests for my code.
package de.hska.iwi.ads.solution.search;
import java.security.acl.LastOwnerException;
import de.hska.iwi.ads.search.Search;
public class BinarySearch<E extends Comparable<E>> implements Search<E> {
#Override
public int search(E[] a, E key, int lower, int upper) {
// TODO Auto-generated method stub
this.lower = lower;
this.upper = upper;
if(upper > a.length) {
throw new ArrayIndexOutOfBoundsException();
}
int ret = binarySearch(a, key, lower, upper);
return returnValue;
}
int lower;
int upper;
int returnValue;
/**
*
* #param a Array, der durchsucht werden soll.
* #param key Element, nach dem gesucht wird.
* #param lower untere Grenze des zu durchsuchenden Bereiches.
* #param upper obere Grenze des zu durchsuchenden Bereiches.
* #return index der Stelle wo daa Elemnt ist.
*/
private int binarySearch(E[] a, E key, int lower, int upper) {
if (lower < upper) {
int middle = (lower / 2) + (upper / 2);
int tempInt = a[middle].compareTo(key);
if (tempInt > 0) {
return binarySearch(a, key, lower, middle - 1);
}
if (tempInt < 0) {
return binarySearch(a, key, middle + 1, upper);
}
this.returnValue = middle;
if (key.equals(a[middle]) && !key.equals(a[middle-1])) {
return middle;
} else {
return binarySearch(a, key, lower, middle-1);
}
}
if (key.equals(a[lower])) {
this.returnValue = lower;
int temp = checkForDuplicates(a, key, 0, upper-1);
return returnValue;
}
int temp = key.compareTo(a[this.upper]);
if(temp > 0) {
this.returnValue = (this.upper + 1);
return (this.upper + 1);
}
temp = key.compareTo(a[this.lower]);
if(temp < 0) {
this.returnValue = this.lower - 1;
return (this.lower - 1);
} else {
this.returnValue = upper + 1;
}
return returnValue;
}
int lastIndex;
private int checkForDuplicates(E[] a, E key, int lower, int upper) {
if (lower < upper) {
int middle = (lower / 2) + (upper / 2);
lastIndex = middle;
int tempInt = a[middle].compareTo(key);
if (tempInt < 0) {
return checkForDuplicates(a, key, middle + 1, upper);
}
this.returnValue = middle;
if (key.equals(a[lower])) {
this.returnValue = lower;
checkForDuplicates(a, key, 0, middle-1);
return returnValue;
}
return -1;
}
if (key.equals(a[lower])) {
this.returnValue = lower;
return returnValue;
}
return -1;
}
}
Try to think about it as "verifying the behaviour".
The behaviour you expect from your BinarySearch class is that for a given array A and an element E, that it will return the index of element E in A if E is an element of A, or -1 if it is not.
A very simple first attempt for tests could look like this:
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayNameGeneration;
import org.junit.jupiter.api.DisplayNameGenerator;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
#DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
class BinarySearchTest {
private BinarySearch<Integer> integerBinarySearch;
#BeforeEach
void setUp() {
integerBinarySearch = new BinarySearch<>();
}
#Test
void returns_index_of_searched_element_when_searched_element_is_in_the_beginning_of_array() {
// given
Integer[] numbers = new Integer[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int numberToSearch = 1;
// when
int indexOfSearchedNumber = integerBinarySearch.search(numbers, numberToSearch, 0, numbers.length - 1);
// then
assertThat(indexOfSearchedNumber).isEqualTo(0);
}
#Test
void returns_index_of_searched_element_when_searched_element_is_in_the_end_of_array() {
// given
Integer[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int numberToSearch = 10;
// when
int indexOfSearchedNumber = integerBinarySearch.search(numbers, numberToSearch, 0, numbers.length - 1);
// then
assertThat(indexOfSearchedNumber).isEqualTo(9);
}
#Test
void returns_index_of_searched_element_when_searched_element_is_in_the_middle_of_array() {
// given
Integer[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
int numberToSearch = 6;
// when
int indexOfSearchedNumber = integerBinarySearch.search(numbers, numberToSearch, 0, numbers.length - 1);
// then
assertThat(indexOfSearchedNumber).isEqualTo(5);
}
#Test
void returns_minus_one_when_element_is_not_in_array() {
// given
Integer[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int numberToSearch = 42;
// when
int indexOfSearchedNumber = integerBinarySearch.search(numbers, numberToSearch, 0, numbers.length - 1);
// then
assertThat(indexOfSearchedNumber).isEqualTo(-1);
}
}
This will tell you for example that your search implementation is not correctly behaving when the element is not in the array. For this program to compile you need to add the junit5 and assertj dependencies to your program. If you're using a build tool like gradle, the following entries need to be added to the dependency block in build.gradle:
testImplementation 'org.junit.jupiter:junit-jupiter:5.4.2'
testImplementation 'org.assertj:assertj-core:3.12.2'

Java - Implementing QuickSort [duplicate]

This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 3 years ago.
I'm learning datastructures and algorithms. So I have tried implementing the quick sort alogorithm.
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr = new int[] { 10, 16, 8, 12, 15, 6, 3, 9, 5 };
quickSort(0, arr.length - 1, arr);
}
public static void quickSort(int start, int end, int[] arr) {
if (start < end) {
int partitionIndex = partition(start, end, arr);
quickSort(start, partitionIndex - 1, arr);
quickSort(partitionIndex+1, end, arr); // When passing partitionIndex+1 in the swap method it throws index out of bound exception
System.out.println(Arrays.toString(arr));
}
}
public static int partition(int start, int end, int[] arr) {
int pivot = arr[end];
int pIndex = start;
for (int i = 0; i < end - 1; i++) {
if (arr[i] <= pivot) {
swap(i, pIndex, arr);
pIndex++;
}
}
swap(pIndex, end, arr);
return pIndex;
}
private static void swap(int i, int index, int[] arr) {
int temp = arr[i];
arr[i] = arr[index]; // index out of bound exception is thrown
arr[index] = temp;
}
When doing the recursive call quickSort(partitionIndex+1, end, arr); and in the swap method it is throwing index out of bound exception. Because there is no such index to retrieve/store the value.
Can any one please help me to resolve this issue?
I assume you tried to implement the Lomuto partition scheme from Wikipedia. If that's the case you have 2 errors in your code, both in the for loop of the partition method:
start index:
You algorithm starts every time at 0. That is causing the IndexOutOfBoundsException, because it swaps pIndex which is array.length at the end. If you fix this, the exception will be gone, but your sorted result will be [3, 5, 8, 10, 12, 15, 6, 16, 9], which is obviously not perfectly sorted.
end condition:
The error here is, that the last iteration is missing every time, because your end condition is i < end - 1 change that to i < end or i <= end - 1 and you should get a perfect result:
[3, 5, 6, 8, 9, 10, 12, 15, 16]
For completion here is the fixed partition method and your quickSort method:
public static void quickSort(int start, int end, int[] arr) {
if (start < end) {
int partitionIndex = partition(start, end, arr);
quickSort(start, partitionIndex - 1, arr);
quickSort(partitionIndex + 1, end, arr);
}
}
public static int partition(int start, int end, int[] arr) {
int pivot = arr[end];
int pIndex = start;
for (int i = start; i < end; i++) {
if (arr[i] < pivot) {
swap(pIndex, i, arr);
pIndex++;
}
}
swap(pIndex, end, arr);
return pIndex;
}

Java: Binary Search

Is this an ok implementation of the binary search algorithm? It works but its an implementation I came up with and differs from my instructors. Can anyone punch a hole in it for me?
package algorithm.linearsearch;
public class BinarySearch {
public static void main(String[] args) {
System.out.println(binarySearch(
new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 26, 109, 1001, 1100 },
26));
}
private static int binarySearch(int[] array, int target) {
int p = 0;
int r = array.length - 1;
int q;
while (p <= r) {
q = (p + r) / 2;
if (array[q] == target) {
System.out.println("value: " + array[q]);
return q;
}
if (array[q] > target) {
r = q + 1;
} else {
p = q - 1;
}
}
return -1;
}
}
Just this
if (array[q] > target) {
r = q + 1;
} else {
p = q - 1;
}
should be
if (array[q] > target) {
r = q - 1; // index lower to current pivot
} else {
p = q + 1; // index upper to current pivot
}
One thing i can say. Your program is expected to return index if found or return -1 if not found. So you don't need to print value as its input taken from user regarding which element to find.
You need a check initially if your array is null return -1 to avoid null pointer exception which will happen when you calculate length of array.

Find the k smallest integer in an array

Here is my code, it works for finding 1-7 smallest integers, but 8 and 9. It returns null when I find 8 smallest integer in the array. Can anyone help me where is the problem? I am using quicksort here.
Thanks very much!
update: I have figured out the problem, which is the array in the main function. After I change to the following look,
int[] arr = {2, 3, 1, 7, 5, 6, 20, 8, 4, 9};
and
if(front>=end) return input;
It works now!
import java.util.Arrays;
import java.io.*;
class quicksort{
public static void main(String[] args){
int[] arr = new int[9];
arr[0] = 7;
arr[1] = 2;
arr[2] = 4;
arr[3] = 8;
arr[4] = 3;
arr[5] = 5;
arr[6] = 1;
arr[7] = 0;
arr[8] = 10;
System.out.println((Arrays.toString(findKSamllest(arr,8))));
}
public static int partition(int[] input, int front, int end){
int pivot = input[front];
while(front < end){
while(input[front]<pivot)
front++;
while(input[end]>pivot)
end--;
swap(input,front,end);
}
return front;
}
public static void swap(int[] input, int s, int l){
int temp = input[s];
input[s] = input[l];
input[l] = temp;
}
public static int[] findK(int[] input, int front, int end, int k){
if(front>=end) return null;
int pivot = partition(input,front,end);
//System.out.println(pivot);
if(k==pivot){
return Arrays.copyOfRange(input,0,pivot);
}
else {
if(k<pivot)
return findK(input,front,pivot,k);
return findK(input,pivot+1,end,k);
}
}
public static int[] findKSamllest(int[] input, int k){
return findK(input, 0, input.length-1, k);
}
}
Change
if(front >= end) return null;
to
if(front > end) return null;
Stand on the shoulders of giants and use the libraries that are already available:
Arrays.sort(myArray);
int[] returnArray = new int(NUM_ITEMS_TO_RETURN);
for (int i=0; i < NUM_ITEMS_TO_RETURN; i++)
{
returnArray[i] = myArray[i];
}
return returnArray;
Obviously you have to do some error checking, for example that the initial array is larger or equal to the number of items you want returned, but that's trivial.
You could save you a bit time and impress your teacher with the fancy new Java 8 API.
It provides streams and useful functions to solve this in one (long) line or 5, if it should be readable ;-)
final List<Integer> sortedKList = Arrays.asList(7, 2, 4, 8, 3, 5, 1, 0, 10)
.stream()
.sorted()
.limit(7)
.collect(Collectors.toList());
You can then review your result with:
sortedKList.forEach(System.out::println);

recursion method with 2d array (java)

i have to write a method,
The method receives a parameter of two-dimensional array of integers. The method returns the number of the row which has the highest sum of the integers.I'm allowed to use only recursion! no loops allowed!-of course i need to make a private method that will sum a row as a single array and then i have to do another private method that compares the rows, but it doesn't really work since the method i wrote is only for a 1d array, and i need to compare a row from a 2d array..
appreciate all kind of help..
some of my code:
private int rowSum(int[] array, int index) {//the sum of an array(1d array)
if (index == array.length)
return 0;
else
return array[index] + rowSum(array, index + 1);
}
**public int maxRow(int[][] a){------!!!---the problem...
}**
I would try calling a recursive method from main with arguments:
array[][]
current column index
current row index
current row sum
highest row index
highest row sum
I got it working here, so it is definitely possible.
It's about 15 lines of code.
Good luck!
As a starter exercise, try to change the signature of your rowSum function into this:
int rowSum(int[] array, int index, int sumSoFar)
You should be able to write the function such that the recursive part's return expression is just a recursive call:
if (...) // exit case
return sumSoFar;
else
return rowSum(...);
(This is now a tail-recursive implementation.)
Armed with that mindset, think about how you would write:
int indexOfMaxValue(int[] array, int index, int maxValueSoFar, int maxIndexSoFar)
Once you get those, you should be able to combine those two concepts together.
The following code is ready to run and test:
public class RecursionSum {
/* Sum a row until <code>index</code>. */
private static int rowSum(int[] a, int index) {
if (index == 0) { return a[0]; }
// add the current element to the recursive sum
return a[index] + rowSum(a, index - 1);
}
/* Sum a whole row. */
private static int rowSum(int[] a) {
return (a.length == 0) ? 0 : rowSum(a, a.length - 1);
}
/* Find the index of the array having the max sum until <code>index</code>. */
private static int maxRow(int[][] a, int index){
if (index == 0) { return 0; }
// compare the current row's sum with the recursive max row's sum,
// update index when it's a new winner
int maxIndex = maxRow(a, index - 1);
return (rowSum(a[maxIndex]) < rowSum(a[index])) ? index : maxIndex;
}
/* Find the index of the array having the max sum. */
public static int maxRow(int[][] a){
return a.length == 0 ? 0 : maxRow(a, a.length - 1);
}
/* very simple test */
public static void main(String[] args) {
int a1[][] = {};
int a2[][] = {{1, 2, 3, 4}};
int a3[][] = {{ 1, 2, 3, 4}, {8, 90}, {5, 6, 7}, {300, 4, 9}, {4, 6, 12}};
System.out.println(maxRow(a1));
System.out.println(maxRow(a2));
System.out.println(maxRow(a3));
}
}
Here is what I came up with...
public static void main(String[] args)
{
int[][] mat = { { 2, 6, 5, 4 }, { 3, 17, 2, 6 }, { 1, 3, 21, 0 } };
System.out.println(maxRow(mat)); // 1
int[][] mat1 = { { 2, 6, 5, 4 }, { 1, 3, 21, 0 }, { 3, 17, 2, 6 } };
System.out.println(maxRow(mat1)); // 2
}
public static int maxRow(int[][] mat)
{
return maxRow(mat, 0, 0, -1);
}
private static int maxRow(int[][] mat, int row, int maxSumInRow, int maxRowNo)
{
if (row == mat.length)
return maxRowNo;
int sumRow = sumRow(mat, row, 0);
if (sumRow > maxSumInRow)
{
maxSumInRow = sumRow;
maxRowNo = row;
}
return maxRow(mat, row + 1, maxSumInRow, maxRowNo);
}
private static int sumRow(int[][] mat, int row, int col)
{
if (col == mat[row].length)
return 0;
return mat[row][col] + sumRow(mat, row, col + 1);
}
Code:
public class MainClass {
static int contents[][] = { {1, 2 , 3, 4} , { 4, 5, 8, 7}, { 4, 2, 8, 7}, { 4, 5, 0, 7} };
public static void main(String[] args)
{
System.out.println(getIndexOfRowWithHighestSum(contents, 0, 0));
}
public static int getIndexOfRowWithHighestSum(int[][] twoDAray, int currentIndex,int indexWithHighestSum){
if(currentIndex>=twoDAray.length){
return indexWithHighestSum;
}
int sum1 = getSumOfArray(twoDAray[currentIndex], 0) ;
int sum2 = getSumOfArray(twoDAray[indexWithHighestSum], 0);
indexWithHighestSum = (sum1 > sum2)?currentIndex:indexWithHighestSum;
return getIndexOfRowWithHighestSum(twoDAray, currentIndex+1,indexWithHighestSum);
}
public static int getSumOfArray(int[] array, int currentIndex){
if(currentIndex>=array.length){
return 0;
}
return array[currentIndex]+getSumOfArray(array,currentIndex+1);
}
}

Categories

Resources