This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 1 year ago.
I know this is an amaetuer error, i understand what it means but i dont understand why i cant fix it. Ive been trying everything. Im trying to take an array of type T and switch its values around so it correctly corresponds to the rules of a heap, where the parent is always greater than the 2 children. The error is in my while loop
please dont be harsh if its something easily fixable. ive been struggling heavily and cant seem to find an answer.
public class myheap<T extends Comparable<T>> extends heap<T>
{
// constructors of the subclass should be written this way:
public myheap(int max) { super(max); }
public myheap(T[] A) {super(A);}
public void buildheap(T[] Arr){
int size = Arr.length;
int startsize = (size-1)/2;
for(int i=startsize;i>0;i--){
int l = left(i);
int r = right(i);
T temp = null;
while((Arr[r]!=null) && Arr[i].compareTo(Arr[r])<0){
if (Arr[l].compareTo(Arr[r])>0){
temp = Arr[l];
Arr[l] = Arr[i];
Arr[i] = temp;
}//if left is greater than right
else //then right must be greater than parent
temp = Arr[r];
Arr[r] = Arr[i];
Arr[i] = temp;
}//whileloop
if((Arr[r]==null) && Arr[i].compareTo(Arr[l])<0)
temp = Arr[l];
Arr[l] = Arr[i];
Arr[i] = temp;
}//for
}//buildheap
public static void main(String[] args){
String[] array = {"SH","AH","AB","YA","AY","AA","AB","LM","LL","LO"};
myheap<String> New = new myheap<String>(array.length);
for(int i=0;i<array.length;i++){
New.insert(array[i]);
}//insert
New.buildheap(array);
New.drawheap();
for(int i=0;i<array.length;i++){
System.out.println(New.deletemax() + " ");
}//for
System.out.println();
} //main
}
Heap superclass that myheap is extending
/*
Polymorphic priority heaps, largest value on top.
Heap axiom. The value at every node cannot be smaller than the values
at each of its children nodes.
Use internal array to implement heap "tree", with index 0 representing
the root. Given node index i, left(i)= 2*i+1 and right(i)=2*i+2, while
parent(i) = (i-1)/2.
*/
class heap<T extends Comparable<T>>
{
protected T[] H; // internal array representing heap.
protected int size; // size of current heap, not same as H.length!
public int size() { return size; } // size is read-only externally.
public int maxsize() { return H.length; }
public heap(T[] A) { H = A; size=0; } // preferred constructor
public heap(int m) // will cause compiler warning (ok to ignore)
{
H = (T[]) new Comparable[m]; // downcast from Object is OK.
size = 0;
}
protected int left(int i) { return 2*i+1; }
protected int right(int i) { return 2*i+2; }
protected int parent(int i) { return (i-1)/2; }
// protected is important!
// lookup heap, without delete
public T getmax()
{
if (size<1) return null;
return H[0];
}
// insert x into heap: place at end, then propagate upwards
// returns false on failure.
public boolean insert(T x)
{
if (size > H.length-1) return false;
H[size++] = x; // place at end, inc size
// propagate upwards
int cur = size-1; // current position
int p = parent(cur);
while (cur>0 && H[cur].compareTo(H[p])>0)
{ // propagate upwards
T temp = H[cur];
H[cur] = H[p]; H[p] = temp;
cur = p; // switch current to parent
p = parent(cur); // recalc parent
}//while
return true;
}//insert
// deletetop: take last element, move to top, propagate downwards:
public T deletemax()
{
if (size<0) return null;
T answer = H[0];
H[0] = H[--size]; // place at top:
// now propagate downwards.
boolean done = false;
int i = 0; // current position
int c = 0; // swap candidate
while (c != -1)
{
int l = left(i);
int r = right(i);
c = -1; // swap candidate
if (l<size && H[l].compareTo(H[i])>0) c = l; // set candidate to left
if (r<size && H[r].compareTo(H[i])>0 && H[r].compareTo(H[l])>0) c=r;
if (c!= -1)
{
T temp = H[i]; H[i] = H[c]; H[c] = temp;
i = c;
}
}//while
return answer;
}//deletemax
// but search is not log(n). Why?
public boolean search(T x)
{
for(int i=0;i<size;i++) {if (x.compareTo(H[i])==0) return true;}
return false;
}
public void drawheap() // use only with heapdisplay.java program
{
heapdisplay W = new heapdisplay(1024,768);
W.drawtree(H,size);
}
}//heap
public class heaps14
{
/**public static void main(String[] args){
heap<Integer> HI = new heap<Integer>(200);
for(int i=0;i<100;i++) HI.insert((int)(Math.random()*1000));
HI.drawheap();
for(int i=0;i<100;i++) System.out.print(HI.deletemax() + " ");
System.out.println();
}//main**/
}
You may check for null in your while loop, (Arr[r]!=null) but the problem is that you can't even get a value from the array to determine if it's null or not. You should check the index is within the range before trying to access the value from the array, using r < Arr.length or similar.
(If null) isnt the problem, arrayIndexOutofBounds means you are geting a value of an array that isnt there
Eg. Array.length =5; and you search Array[6]; - out of bounds....
The problem i think is your method right(i);
which is. i*2+2 and the array
So change the for loop to this
for(int i=startsize-2;i>0;i--)
comment if this helps.
Related
So I'm working with the java implementation of Max Heaps. My Insert, bubbleUp and deleteMax (on its own) methods seem to work fine, but my heapsort method (which calls deleteMax) doesn't work as its supposed to (it doesn't cause an error message; it just doesn't sort them in the order it's supposed to). I've included the code below. Any help understanding the problem is greatly appreciated. Thanks!
The whole class can be found at: https://repl.it/repls/FrequentPartialBlockchain
'''
public int deleteMax(){
if(this.numNodes == 0)
throw new NoSuchElementException();
else if(this.numNodes == 1){
int elemToReturn = heapArr[0];
heapArr[0] = null;
return elemToReturn;
}
int elemToReturn = heapArr[0];
heapArr[0] = heapArr[numNodes-1];
heapArr[numNodes-1] = null;
this.numNodes--;
bubbleDown();
return elemToReturn;
}
private void bubbleDown(){
int n = 0;
int L = 2 * n + 1; // L will hold the index of the left child
while(L < this.numNodes - 1){
int max = L;
int R = L + 1; // R will hold the index of the right child
if(R < this.numNodes - 1){
if(heapArr[R] >= heapArr[L])
max++;
}
int temp;
if(heapArr[n] < heapArr[max]){
// swap
temp = heapArr[n];
heapArr[n] = heapArr[max];
heapArr[max] = temp;
n = max;
L = 2 * n + 1;
}
else{
break;
}
}
}
public static void heapsort(Integer[] arrayToSort){
MaxHeap tempHeap = new MaxHeap(arrayToSort);
for(int i = 0; i < tempHeap.numNodes; i++)
arrayToSort[i] = (Integer) tempHeap.deleteMax();
}
'''
This while statement seems wrong:
while(L < this.numNodes - 1){
If this.numNodes is the number of nodes in the heap, then this.numNodes - 1 is the last node. This condition, then, prevents the loop from being entered if L is the last node in the heap.
On a related note, your special case in deletMax is broken. You remove the only node in the heap, but you forgot to set numNodes to 0.
I am working on Replacement Selection sort project but i keep getting the error Exception in thread main Java.lang.ArrayIndexOutOfBoundsException:10 at ReplacementSelection.swap(ReplacementSelection.java:42) at ReplacementSelection.siftDown(ReplacementSelection.java:69) at Replacement..
class ReplacementSelection {
static int[] array = new int[]{ 1,2,3,4,5,6,7,8,9,10 };
public static void sort() {
System.out.println("before:" + Arrays.toString(array));
for (int i = array.length/2; i >= 0; i--) {
siftDown(i);
}
int count = array.length-1;
while (count > 0)
{
swap(array[0], array[count]);
--count;
siftDown(0);
}
System.out.println("after:" + Arrays.toString(array));
}
public static void swap(int i, int j)
{
int tmp;
tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
public static void siftDown(int index)
{
int count = array.length;
// Left child is at index*2+1. Right child is at index*2+2;
while (true)
{
// first find the largest child
int largestChild = index*2+1;
// if left child is larger than count, then done
if (largestChild >= count)
{
break;
}
// compare with right child
if (largestChild+1 < count && array[largestChild] < array[largestChild+1])
{
++largestChild;
}
// If item is smaller than the largest child, then swap and continue.
if (array[index] < array[largestChild])
{
swap(array[index], array[largestChild]);
index = largestChild;
}
else
{
break;
}
}
}
public static void main(String[] args){
ReplacementSelection a = new ReplacementSelection();
a.sort();
}
}
You have written a swap method which takes indices as arguments. However, you pass it the values in the array at those indices instead of the indices themselves:
swap(array[0], array[count]);
and
swap(array[index], array[largestChild]);
To fix the exception error just pass the indices to the method:
swap(0, count);
and
swap(index, largestChild);
As #Pajacar123 mentioned, you should learn to use debugger.
In line
swap(array[index], array[largestChild]);
You are passing value from array which is at last index of table(index 9 value 10). Then when in method sawp in line array[i] = array[j];
j value is 10 while max index of table is 9. That causes exception. You are trying to refer to not existing elemnt.
Current I have a home work question which says,
It is possible to make the heap sort algorithm more efficient by
writing a method that will order the entire list at once instead of
adding the elements one at a time.
However I can't figure out what exactly it means by "instead of adding elements one at a time", surely one has to building a heap first (which involves adding element from a unsorted list one by one), then remove the largest from the heap one at a time.
Here is my heap array:
import exceptions.exceptions.*;
public class ArrayHeap<T> extends ArrayBinaryTree<T> implements HeapADT<T> {
public ArrayHeap(){
super();
}
public void addElement (T element){
if (count==size())
expandCapacity();
tree[count] = element;
count++;
if (count > 1)
heapifyAdd();
}
private void heapifyAdd(){
int index = count - 1;
while ((index != 0) && (((Comparable)tree[index]).compareTo(tree[(index-1)/2]) < 0))
{
T temp = tree[index];
tree[index] = tree[(index-1)/2];
tree[(index-1)/2] = temp;
index = (index-1)/2;
}
}
public T removeMin(){
if (isEmpty())
throw new EmptyCollectionException ("Empty Heap");
T minElement = findMin();
tree[0] = tree[count-1];
heapifyRemove();
count--;
return minElement;
}
private void heapifyRemove()
{
T temp;
int node = 0;
int left = 1;
int right = 2;
int next;
if ((tree[left] == null) && (tree[right] == null))
next = count;
else if (tree[left] == null)
next = right;
else if (tree[right] == null)
next = left;
else if (((Comparable)tree[left]).compareTo(tree[right]) < 0)
next = left;
else
next = right;
while ((next < count) && (((Comparable)tree[next]).compareTo(tree[node]) < 0)){
temp = tree[node];
tree[node] = tree[next];
tree[next] = temp;
node = next;
left = 2*node + 1;
right = 2*(node+1);
if ((tree[left] == null) && (tree[right] == null))
next = count;
else if (tree[left] == null)
next = right;
else if (tree[right] == null)
next = left;
else if (((Comparable)tree[left]).compareTo(tree[right]) < 0)
next = left;
else
next = right;
}
}
public T findMin() {
if (isEmpty())
throw new EmptyCollectionException ("Empty Heap");
return tree[0];
}
}
Here is more HeapSort algorithm:
import ArrayHeap;
public class HeapSort<T>{
public T[] heapsort(T[] data, int min, int max){
ArrayHeap<T> temp = new ArrayHeap<T>();
for (int c = min; c <= max; c++){
temp.addElement(data[c]);
}
int count = min;
while(!(temp.isEmpty())){
T jj = temp.removeMin();
data[count] = jj;
count ++;
}
return data;
}
The most straight-forward way to perform heapsort is to use a separate heap and add all the elements to it, then the elements will be in order when we pop them out one by one. This is what "adding the elements one at a time" refers to in the statement, and this is what your implementation is doing: create a heap of type ArrayHeap and insert the elements of data to it, in the end pop the elements back to data.
A more efficient way (in terms of both space and time) is to perform in-place sorting, where we use the array to be sorted as the heap, rather than using additional memory for the heap, this is what "order the entire list at once" refers to. The steps of this implementation is as follow, we will order the elements in non-decreasing order:
We max-heapify the input array (i.e. we re-arrange the elements in the array so that it follows the max-heap property.
For i = n - 1 to 1:
Swap the 0-th element in the array with the i-th element.
Decrease the size of the heap by 1 (i.e. the heap should be of size i).
Perform the sift-down operation on the heap to restore the max-heap property.
Note that whenever the max-heap property holds, the top-most element in the heap is the largest element, so at the start of the k-th iteration (k = n - i here) the 0-th element is the k-largest element, and we place is in the correct position in the array by swapping.
Note that step 1 can be done in O(n), and in step 2 there are O(n) iterations and each sift-down operation takes time O(log(n)), so the overall time complexity is O(n log(n)).
Below is an implementation in Java for your reference:
import java.util.Random;
public class HeapSort {
public static void main(String[] args) {
for (int i = 1; i <= 10; i++) {
System.out.println(String.format("Iteration number %d%n", i));
Integer[] array = randomIntArray(10, 0, 100);
System.out.println(String.format("Array before sorting: [%s]", toStr(array)));
heapSort(array);
System.out.println(String.format("Array after sorting: [%s]", toStr(array)));
System.out.println("================================================================");
}
}
private static <T extends Comparable<T>> T[] heapSort(T[] array) {
maxHeapify(array, array.length);
for (int i = array.length - 1; i > 0; i--) {
swap(array, 0, i);
siftDown(array, i, 0);
}
return array;
}
private static <T extends Comparable<T>> void maxHeapify(T[] array, int heapSize) {
for (int i = getParentIdx(heapSize - 1); i >= 0; i--) {
siftDown(array, heapSize, i);
}
}
private static <T extends Comparable<T>> void siftDown(T[] array, int heapSize, int idx) {
final int length = Math.min(array.length, heapSize) - 1;
if (idx > length || idx < 0) throw new IllegalArgumentException("Index out of range");
while (true) {
int maxIdx = idx;
int leftChildIdx = getLeftChildIdx(idx);
int rightChildIdx = getRightChildIdx(idx);
if (leftChildIdx <= length && array[maxIdx].compareTo(array[leftChildIdx]) < 0) maxIdx = leftChildIdx;
if (rightChildIdx <= length && array[maxIdx].compareTo(array[rightChildIdx]) < 0) maxIdx = rightChildIdx;
if (idx != maxIdx) {
swap(array, idx, maxIdx);
idx = maxIdx;
} else {
return;
}
}
}
private static int getParentIdx(int idx) {
return (idx - 1) / 2;
}
private static int getLeftChildIdx(int idx) {
return idx * 2 + 1;
}
private static int getRightChildIdx(int idx) {
return idx * 2 + 2;
}
private static <T> void swap(T[] array, int i, int j) {
T tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
private static <T> String toStr(T[] array) {
StringBuilder sb = new StringBuilder();
for (T element : array) {
sb.append(element + ", ");
}
return sb.substring(0, sb.length() - 2);
}
private static Integer[] randomIntArray(int size, int lowerBound, int upperBound) {
Integer[] result = new Integer[size];
Random random = new Random();
int diff = upperBound - lowerBound + 1;
for (int i = 0; i < size; i++) result[i] = lowerBound + random.nextInt(diff);
return result;
}
}
I am doing an algorithm for a hill climbing search, and for some reason, the stack that I'm supposed to have at the end of the loop seems to be overwritten with the last iteration of the state that the loop generated.
Basically, here is a rundown of what this algorithm is doing:
This algorithm is being used to solve the N queens problem. All of the underlying code with the state class works perfectly fine. With this algorithm, it iterates through all possible successor states of the current state. It stores the next successor state within the neighborState variable (as seen in the code below). If a state cost is less than the current cost, it will add the neighborState with that new low cost into a neighborNode and store that into a stack. Any new min values that get detected will wipe the stack and insert the new lowest minimum nodes.
I've done a few tests within the loop to see what the outputs look like from what is being inserted into the stack. All of them seem to be correctly outputting. However, when I am outside the loop and check the stack, all the nodes in the stack have their states replaced to the last generated successor state from the loop. It seems that in every node that has the neighborState stored, each time the neighborState updates, it changes all the node neighborState values as well. I just can't seem to find a way to fix this though.
Some advice as to how I can fix this would be greatly appreciated!
*Note: Disregard the code after the for loop starting at the if statement, as it is still incomplete.
Here is the code:
import java.util.Random;
import java.util.Stack;
public class HillClimber {
private LocalSearchNode _current;
private int _shoulderSearchStepsAllowed;
// may need more instance variables
public HillClimber(LocalSearchNode initial, int searchShoulder) {
_current = initial;
_shoulderSearchStepsAllowed = searchShoulder;
}
public LocalSearchNode findSolution() {
LocalSearchNode neighborNode = null;
//Stack <LocalSearchNode> nodeStack;
State currentState = null;
//State neighborState = null;
Double val = 0.0;
boolean start = true;
while (true) {
currentState = _current.getState();
Stack<LocalSearchNode> nodeStack = new Stack<LocalSearchNode>();
// finds the highest valued successor of current
for (String s : currentState.actions()) {
State neighborState = currentState.successor(s);
Double cost = neighborState.estimatedDistance(neighborState);
// execute this for the first successor found
if (start) {
val = cost;
System.out.println("Started with " + val);
neighborNode = new LocalSearchNode(neighborState,
s, val, 0);
nodeStack.push(neighborNode);
start = false;
((QState) nodeStack.peek().getState()).test();
System.out.println(nodeStack.size());
}
// resets node array if new min found and adds it to the array
else if (cost < val) {
System.out.println("Reset " + val + " with " + cost);
val = cost;
nodeStack = new Stack<LocalSearchNode>();
neighborNode= new LocalSearchNode(neighborState,
s, val, 0);
nodeStack.push(neighborNode);
((QState) nodeStack.peek().getState()).test();
System.out.println(nodeStack.size());
}
// if cost is the same as current min val, add it to the array
else if (cost.equals(val)) {
val = cost;
System.out.println("Added " + val);
neighborNode = new LocalSearchNode(neighborState,
s, val, 0);
nodeStack.push(neighborNode);
((QState) nodeStack.peek().getState()).test();
System.out.println(nodeStack.size());
}
}
System.out.println("Final min " + val);
System.out.println(nodeStack.size());
((QState) nodeStack.elementAt(0).getState()).test();
((QState) nodeStack.elementAt(1).getState()).test();
// returns current state if no better state found
if (_current.getValue() < val) {
// System.out.println(val);
// ((QState) _current.getState()).test();
return _current;
} else {
if (nodeStack.size() > 1) {
Random generator = new Random();
int i = generator.nextInt(nodeStack.size());
_current = nodeStack.elementAt(i);
} else {
_current = nodeStack.firstElement();
}
start = true;
}
}
}
}
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class QState implements State {
private List<String> _list;
private int[][] _state;
private int[] _qlist;
/**
* Constructor takes in the board and row index value corresponding to the
* queens at their respective column index
*
* #param state
* #param queens
*/
public QState(int[][] state, int[] queens) {
_state = state;
_qlist = queens;
_list = new ArrayList<String>();
// generates a list of all possible actions for this state
for (int i = 0; i < _qlist.length; i++) {
for (int j = 0; j < _qlist.length; j++) {
if (_state[i][j] != -1) {
_list.add("Move queen " + j + " to row " + i);
}
}
}
}
/**
* Returns a list of N * (N - 1) actions
*/
public List<String> actions() {
return _list;
}
/**
* Returns the matrix board configuration of this state
*
* #return
*/
public int[][] getMatrix() {
return _state;
}
/**
* Returns the array of queens row index for the board configuration
*
* #return
*/
public int[] getQList() {
return _qlist;
}
/**
* Parses the action and moves the queen to the new board location
*/
public State successor(String action) {
State temp = null;
int[][] newState = _state;
int[] newQList = _qlist;
String[] vals = action.split("\\s");
int i = Integer.parseInt(vals[5]); // parses the row index
int j = Integer.parseInt(vals[2]); // parses the column index
newState[_qlist[j]][j] = 0; // clears the old queen
newState[i][j] = -1; // sets the new queen
newQList[j] = i; // adds the new queen to the list
temp = new QState(newState, newQList);
return temp;
};
/**
* Returns the default step cost of 1.0
*/
public Double stepCost(String action) {
return 1.0;
}
// overrides the built-in Java equals method
#Override
public boolean equals(Object s) {
if (s == null) {
return false;
}
if (this.getClass() != s.getClass()) {
return false;
}
if (!Arrays.equals(this.getMatrix(), ((QState) s).getMatrix())) {
return false;
}
return true;
}
/**
* Returns the queen conflicts for the particular board
*/
public Double estimatedDistance(State s) {
double conflicts = 0.0;
int col = 0;
int row = 0;
for (int j = 0; j < _qlist.length; j++) {
row = _qlist[j] - 1;
col = j + 1;
// checks the upper right diagonal for queen conflicts
while (row >= 0 && col < _qlist.length) {
if (_state[row][col] == -1) {
conflicts++;
}
row--;
col++;
}
row = _qlist[j] + 1;
col = j + 1;
// checks the lower right diagonal for queen conflicts
while (row < _qlist.length && col < _qlist.length) {
if (_state[row][col] == -1) {
conflicts++;
}
row++;
col++;
}
row = _qlist[j];
col = j + 1;
// checks the sideways right for queen conflicts
while (col < _qlist.length) {
if (_state[row][col] == -1) {
conflicts++;
}
col++;
}
}
// test();
return conflicts;
}
public void test() {
for (int i = 0; i < _qlist.length; i++) {
for (int j = 0; j < _qlist.length; j++) {
if (_state[i][j] == -1) {
System.out.print("Q");
} else {
System.out.print("-");
}
}
System.out.println("");
}
System.out.println("\n");
}
}
If you look at successor, this looks suspicious to me:
int[][] newState = _state;
int[] newQList = _qlist;
Here, it looks like you're sharing these arrays between objects. Without knowing much about what the program is doing, this kind of thing is typically the cause of the "shared update" behavior you've observed.
So updating the array from the returned successor will also change the state of the object that returned it (and so on).
There are a couple of easy ways to copy an array, namely System#arraycopy, Arrays#copyOf and clone. (All arrays are cloneable.) For the 2D array you might want to make a helper method since you'd probably need to make a deep copy. Something like:
static int[][] copyState(int[][] toCopy) {
int[][] copy = new int[toCopy.length][];
for(int i = 0; i < copy.length; i++) {
// or = Arrays.copyOf(toCopy[i], toCopy[i].length);
copy[i] = toCopy[i].clone();
}
return copy;
}
I didn't spend a whole lot of time really parsing the code--there's a lot to go through, sorry--but I don't see you making a copies anywhere, just mutating them, so I'd put my bet on this.
How can i implement a recursive binary search in an int array using only 1 parameter in java ?
it tried but my code doesn't work. I implemented a class which its instances are objects having arrays and a count variable to detect how many elements are their in the array. any idea how can i implement the recursive binary search using only 1 parameter ?
public class LinearSortedArray {
int count;
int[] a;
public LinearSortedArray() {
count = 0;
}
public LinearSortedArray(int size) {
count = 0;
a = new int[size];
}
public static int[] copyingMethod(int startPoint, int endPoint,
LinearSortedArray arrayObj) {
int[] copyingArray = new int[endPoint - startPoint];
int j = startPoint;
for (int i = 0; i < copyingArray.length; i++) {
copyingArray[i] = arrayObj.a[j];
j++;
}
return copyingArray;
}
public int binarySearchRec(int x) {
if (count == 0) {
return -1;
}
int pivot = count / 2;
LinearSortedArray newArrayObj;
if (x > a[pivot]) {
newArrayObj = new LinearSortedArray(count - pivot);
newArrayObj.count = newArrayObj.a.length;
newArrayObj.a = copyingMethod(pivot, count, this);
for (int i = 0; i < newArrayObj.a.length; i++) {
System.out.print(newArrayObj.a[i]);
System.out.print(" ");
}
System.out.println();
return pivot + newArrayObj.binarySearchRec(x);
} else if (x < a[pivot]) {
newArrayObj = new LinearSortedArray(pivot);
newArrayObj.count = newArrayObj.a.length;
newArrayObj.a = copyingMethod(0, pivot, this);
for (int i = 0; i < newArrayObj.a.length; i++) {
System.out.print(newArrayObj.a[i]);
System.out.print(" ");
}
System.out.println();
return newArrayObj.binarySearchRec(x);
} else {
return pivot;
}
}
}
P.S.: The arrays are already sorted
Binary search really requires a range and a target value -- so if you're only passing one parameter, this has to be the target and this must encapsulate the array & range.
public class ArraySegment {
protected int[] array;
protected int boundLo;
protected int boundHi;
public class ArraySegment (int[] array) {
// entire array.
this( array, 0, array.length);
}
public class ArraySegment (int[] array, int lo, int hi) {
this.array = array;
this.boundLo = lo;
this.boundHi = hi;
}
public int binarySearch (int target) {
if (boundHi <= boundLo) {
return -1; // Empty; not found.
}
int pivot = (boundLo + boundHi) / 2;
int pivotEl = array[ pivot];
if (target == pivotEl) {
return pivot; // Found!
}
if (target < pivotEl) {
// recurse Left of pivot.
ArraySegment sub = new ArraySegment( array, boundLo, pivot);
return sub.binarySearch( target);
} else {
// recurse Right of pivot.
ArraySegment sub = new ArraySegment( array, pivot, boundHi);
return sub.binarySearch( target);
}
}
}
It's a little bit questionable what kind of result you should return -- there isn't a good answer with the question posed like this, as an "integer index" kinda defeats the purpose of the ArraySegment/ range wrapper, and returning an ArraySegment containing only the found value is also fairly useless.
PS: You really shouldn't be copying the array or it's contents, just passing round references to ranges on that array. Like java.lang.String is a range on a character array.
You could contrive a single-parameter by using the Value Object Pattern, where you pass one "wrapper" object, but the object has many fields.
For example:
class SearchParams {
int target;
int start;
int end;
SearchParams(t, s, e) {
target = t;
start = s;
end = e'
}
}
int search(SearchParams params) {
// some impl
return search(new SearchParams(params.target, a, b));
}
Technically, this is one parameter. Although it may not be in the spirit of the rules.