Related
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.
running into a silly error and I just don't see it. I've been looking at this for a while and don't see what I'm missing. I am recursively searching an array for a specific target number but once I get up to element [7] it begins returning -1. Thanks for taking a look fellas/ladies!
public static void main(String[] args)
{
int[] a = {1,25,2,6,4,3,23,30,32,14,11,8};
Arrays.sort(a);
int target = a[7];
int first = a[0];
int last = a.length;
for(int i=0;i<a.length;i++)
{
System.out.print(" "+a[i]);
}
System.out.println("\n"+binarySearch(target,first,last,a));
}
public static int binarySearch(int target,int first, int last, int[] a)
{
int result;
if(first>last)
return -1;
else
{
int mid = (first+last)/2;
if(target == mid)
result = mid;
else if(target<a[mid])
result = binarySearch(target,first,last-1,a);
else
result = binarySearch(target,mid+1,last,a);
}
return result;
}
In several places you fail to accurately distinguish between the value in an index of an array and the index itself.
This: a[i] gets the value at the ith element
This: i is simply an index, i
With that in mind, here is a fixed version of your code. See my comments in the code for some specific errors I fixed:
public static void main(String[] args)
{
int[] a = {1,25,2,6,4,3,23,30,32,14,11,8};
Arrays.sort(a);
int target = a[7];
//here you want the index of the first location to search, not the value in that index
//so you use 0 instead of a[0]
int first = 0;
//the last element index is length-1, not length, since arrays are 0-based
int last = a.length - 1;
for(int i=0;i<a.length;i++)
{
System.out.print(" "+a[i]);
}
System.out.println("\n"+binarySearch(target,first,last,a));
}
public static int binarySearch(int target,int first, int last, int[] a)
{
int result;
if(first>last)
return -1;
else
{
int mid = (first+last)/2;
//here you need to check if the target is equal to the value at the index mid
//before you were checking if the target was equal to the index, which was never true
if(target == a[mid])
//you want to return the value at the target, not the index of the target
//so use a[mid] not mid
result = a[mid];
else if(target<a[mid])
//here you want to search from first to mid-1
//before you were searching from first to last-1, which is not correct binary search
result = binarySearch(target,first,mid - 1,a);
else
result = binarySearch(target,mid + 1,last,a);
}
return result;
}
I have a program that I'm trying to make for class that returns the sum of all the integers in an array using recursion. Here is my program thus far:
public class SumOfArray {
private int[] a;
private int n;
private int result;
public int sumOfArray(int[] a) {
this.a = a;
n = a.length;
if (n == 0) // base case
result = 0;
else
result = a[n] + sumOfArray(a[n-1]);
return result;
} // End SumOfArray method
} // End SumOfArray Class
But I'm getting three error which are all related, I believe, but I can't figure out why it is finding a type of null:
SumOfArray.java:25: sumOfArray(int[]) in SumOfArray cannot be applied to (int)
result = a[n] + sumOfArray(a[n-1]);
^
SumOfArray.java:25: operator + cannot be applied to int,sumOfArray
result = a[n] + sumOfArray(a[n-1]);
^
SumOfArray.java:25: incompatible types
found : <nulltype>
required: int
result = a[n] + sumOfArray(a[n-1]);
^
3 errors
The solution is simpler than it looks, try this (assuming an array with non-zero length):
public int sumOfArray(int[] a, int n) {
if (n == 0)
return a[n];
else
return a[n] + sumOfArray(a, n-1);
}
Call it like this:
int[] a = { 1, 2, 3, 4, 5 };
int sum = sumOfArray(a, a.length-1);
The issue is that a[n-1] is an int, whereas sumOfArray expects an array of int.
Hint: you can simplify things by making sumOfArray take the array and the starting (or ending) index.
a[n-1]
is getting the int at n-1, not the array from 0 to n-1.
try using
Arrays.copyOf(a, a.length-1);
instead
How about this recursive solution? You make a smaller sub-array which contains elements from the second to the end. This recursion continues until the array size becomes 1.
import java.util.Arrays;
public class Sum {
public static void main(String[] args){
int[] arr = {1,2,3,4,5};
System.out.println(sum(arr)); // 15
}
public static int sum(int[] array){
if(array.length == 1){
return array[0];
}
int[] subArr = Arrays.copyOfRange(array, 1, array.length);
return array[0] + sum(subArr);
}
}
a is an int array. Thus a[n-1] is an int. You are passing an int to sumOfArray which expects an array and not an int.
Try this if you don't want to pass the length of the array :
private static int sumOfArray(int[] array) {
if (1 == array.length) {
return array[array.length - 1];
}
return array[0] + sumOfArray(Arrays.copyOfRange(array, 1, array.length));
}
Offcourse you need to check if the array is empty or not.
This is the one recursive solution with complexity O(N).and with input parameter A[] only.
You can handle null and empty(0 length) case specifically as Its returning 0 in this solution. You throw Exception as well in this case.
/*
* Complexity is O(N)
*/
public int recursiveSum2(int A[])
{
if(A == null || A.length==0)
{
return 0;
}
else
{
return recursiveSum2Internal(A,A.length-1);
}
}
private int recursiveSum2Internal(int A[],int length)
{
if(length ==0 )
{
return A[length];
}
else
{
return A[length]+recursiveSum2Internal(A, length-1);
}
}
without any predefined function.
public static int sum(int input[]) {
int n = input.length;
if (n == 0) // base case
return 0;
int small[]=new int[n-1];
for(int i=1;i<n;i++)
{
small[i-1]=input[i];
}
return input[0]+sum(small);
}
private static int sum(int[] arr) {
// TODO Auto-generated method stub
int n = arr.length;
if(n==1)
{
return arr[n-1];
}
int ans = arr[0]+sum(Arrays.copyOf(arr, n-1));
return ans;
}
Simplified version:
//acc -> result accumlator, len - current length of array
public static int sum(int[] arr, int len, int acc) {
return len == 0 ? acc : sum(arr, len-1, arr[len-1]+ acc);
}
public static void main(String[] args) {
int[] arr= { 5, 1, 6, 2};
System.out.println(sum(arr, arr.length, 0));
}
For one of the questions i was asked to solve, I found the max value of an array using a for loop, so i tried to find it using recursion and this is what I came up with:
public static int findMax(int[] a, int head, int last) {
int max = 0;
if (head == last) {
return a[head];
} else if (a[head] < a[last]) {
return findMax(a, head + 1, last);
} else {
return a[head];
}
}
So it works fine and gets the max value, but my question is : is it ok to have for the base case return a[head] and for the case when the value at the head is > the value at last?
You could just as easily do it with only one counter, just the index of the value you want to compare this time:
public static int findMax(int[] a, int index) {
if (index > 0) {
return Math.max(a[index], findMax(a, index-1))
} else {
return a[0];
}
}
This much better shows what is going on, and uses the default "recursion" layout, e.g. with a common base step. Initial call is by doing findMax(a, a.length-1).
It's actually much simpler than that. The base case is if you've reached the end of the array (the 'else' part of the ternary control block below). Otherwise you return the max of the current and the recursive call.
public static int findMax(int[] a) {
return findMax(a, 0);
}
private static int findMax(int[] a, int i) {
return i < a.length
? Math.max(a[i], findMax(a, i + 1))
: Integer.MIN_VALUE;
}
At each element, you return the larger of the current element, and all of the elements with a greater index. Integer.MIN_VALUE will be returned only on empty arrays. This runs in linear time.
I would solve this by dividing the array in to the half on each recursive call.
findMax(int[] data, int a, int b)
where a and b are array indices.
The stop condition is when b - a <= 1, then they are neighbours and the max is max(a,b);
The initial call:
findMax(int[] data, int 0, data.length -1);
This reduces the maximum recursion depth from N to log2(N).
But the search effort still stays O(N).
This would result in
int findMax(int[] data, int a, int b) {
if (b - a <= 1) {
return Math.max(data[a], data[b]);
} else {
int mid = (a+b) /2; // this can overflow for values near Integer.Max: can be solved by a + (b-a) / 2;
int leftMax = findMax(a, mid);
int rightMax = findMax(mid +1, b);
return Math.max(leftMax, rightMax);
}
}
I came across this thread and it helped me a lot. Attached is my complete code in both recursion and divide&conquer cases.
The run time for divide&conquer is slightly better than recursion.
//use divide and conquer.
public int findMaxDivideConquer(int[] arr){
return findMaxDivideConquerHelper(arr, 0, arr.length-1);
}
private int findMaxDivideConquerHelper(int[] arr, int start, int end){
//base case
if(end - start <= 1) return Math.max(arr[start], arr[end]);
//divide
int mid = start + ( end - start )/2;
int leftMax =findMaxDivideConquerHelper(arr, start, mid);
int rightMax =findMaxDivideConquerHelper(arr, mid+1, end);
//conquer
return Math.max( leftMax, rightMax );
}
// use recursion. return the max of the current and recursive call
public int findMaxRec(int[] arr){
return findMaxRec(arr, 0);
}
private int findMaxRec(int[] arr, int i){
if (i == arr.length) {
return Integer.MIN_VALUE;
}
return Math.max(arr[i], findMaxRec(arr, i+1));
}
What about this one ?
public static int maxElement(int[] a, int index, int max) {
int largest = max;
while (index < a.length-1) {
//If current is the first element then override largest
if (index == 0) {
largest = a[0];
}
if (largest < a[index+1]) {
largest = a[index+1];
System.out.println("New Largest : " + largest); //Just to track the change in largest value
}
maxElement(a,index+1,largest);
}
return largest;
}
I know its an old Thread, but maybe this helps!
public static int max(int[] a, int n) {
if(n < 0) {
return Integer.MIN_VALUE;
}
return Math.max(a[n-1], max(a, n - 2));
}
class Test
{
int high;
int arr[];
int n;
Test()
{
n=5;
arr = new int[n];
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
arr[3] = 40;
arr[4] = 50;
high = arr[0];
}
public static void main(String[] args)
{
Test t = new Test();
t.findHigh(0);
t.printHigh();
}
public void printHigh()
{
System.out.println("highest = "+high);
}
public void findHigh(int i)
{
if(i > n-1)
{
return;
}
if(arr[i] > high)
{
high = arr[i];
}
findHigh(i+1);
return;
}
}
You can do it recursively as follows.
Recurrent relation it something like this.
f(a,n) = a[n] if n == size
= f(a,n+1) if n != size
Implementation is as follows.
private static int getMaxRecursive(int[] arr,int pos) {
if(pos == (arr.length-1)) {
return arr[pos];
} else {
return Math.max(arr[pos], getMaxRecursive(arr, pos+1));
}
}
and call will look like this
int maxElement = getMaxRecursive(arr,0);
its not okay!
your code will not find the maximum element in the array, it will only return the element that has a higher value than the elements next to it, to solve this problem,the maximum value element in the range can be passed as argument for the recursive method.
private static int findMax(int[] a, int head, int last,int max) {
if(last == head) {
return max;
}
else if (a[head] > a[last]) {
max = a[head];
return findMax(a, head, last - 1, max);
} else {
max = a[last];
return findMax(a, head + 1, last, max);
}
}
Optimized solution
public class Test1 {
public static int findMax(int[] a, int head, int last) {
int max = 0, max1 = 0;
if (head == last) {
return a[head];
} else if (a[head] < a[last]) {
max = findMax(a, head + 1, last);
} else
max = findMax(a, head, last - 1);
if (max >= max1) {
max1 = max;
}
return max1;
}
public static void main(String[] args) {
int arr[] = {1001, 0, 2, 1002, 2500, 3, 1000, 7, 5, 100};
int i = findMax(arr, 0, 9);
System.out.println(i);
}
}
Thanks #Robert Columbia for the suggestion!
Update: This following function is going to recursively start from index 0 and it will keep adding to this index value till it's equal to the Length of the array, if it's more we should stop and return 0. Once we're doing that, we need to get the max of every two items in the array so, for example:
A = [1 , 2 , 3 ];
A[0] ( 1 ) vs A[1] ( 2 ) = 2
A[1] ( 2 ) vs A[2] ( 3 ) = 3
Max(2,3) = 3 ( The answer )
public int GetMax(int [] A, int index) {
index += 1;
if (index >= A.Length) return 0;
return Math.Max(A[index], GetMax(A, index + 1));
}
static int maximumOFArray(int[] array,int n) {
int max=Integer.MIN_VALUE;
if(n==1) return array[0];
else
max=maximumOFArray(array, --n);
max= max>array[n] ? max : array[n];
return max;
}
private static int getMax(int [] arr, int idx) {
if (idx==arr.length-1 ) return arr[idx];
return Math.max(arr[idx], getMax (arr,idx+1 ));
}
public class FindMaxArrayNumber {
public static int findByIteration(int[] array) {
int max = array[0];
for (int j : array) {
max = Math.max(j, max);
}
return max;
}
public static int findByRecursion(int[] array, int index) {
return index > 0
? Math.max(array[index], findByRecursion(array, index - 1))
: array[0];
}
public static void main(String[] args) {
int[] array = new int[]{1, 2, 12, 3, 4, 5, 6};
int maxNumberByIteration = findByIteration(array);
int maxNumberByRecursion = findByRecursion(array, array.length - 1);
System.out.println("maxNumberByIteration: " + maxNumberByIteration);
System.out.println("maxNumberByRecursion: " + maxNumberByRecursion);
// Outputs:
// maxNumberByIteration: 12
// maxNumberByRecursion: 12
}
}
int maximum = getMaxValue ( arr[arr.length - 1 ], arr, arr.length - 1 );
public static int getMaxValue ( int max, int arr[], int index )
{
if ( index < 0 )
return max;
if ( max < arr[index] )
max = arr[index];
return getMaxValue ( max, arr, index - 1 );
}
I felt that using a tracker for current maximum value would be good.
I am trying to find out the majority Element in an array ad this code is working fine when I am checking with elements less than size. But it is giving me arrayindexoutofbound exception whenever any element is equal to size of array. Please let me know how to resolve this.
public class MajorityElement {
public static void main(String[] args) {
int a[]={2,2,7,5,2,2,6};
printMajority(a, 7);
}
//1st condition to check if element is in majority.
public static int findCandidate(int a[], int size){
int maj_index=0;
int count =1;
int i;
size=a.length;
for(i=1;i<a.length;i++ ){
if(a[maj_index]==a[i])
count++;
else
count--;
if(count==0)
{
maj_index=a[i]; //current element takes max_inex position.
count =1;
}
}
return a[maj_index];
}
public static boolean isMajority(int a[], int size, int cand){
int i, count =0;
for(i=0;i<a.length;i++)
{
if(a[i]==cand)
count++;
}
if(count>size/2){
return true;
}
else {
return false;
}
}
private static void printMajority(int a[],int size){
size=a.length;
int cand=findCandidate( a, 7);
if(isMajority(a,size,cand))
System.out.printf("%d",cand);
else
System.out.println("no such element as majority");
}
}
The problem is in the maj_index=a[i]; line. You take the value of one of the cells of the array and assign it to maj_index which is subsequently used as an index into the array (see a[maj_index] == a[i]). Thus, if the value at that position was larger than the size of the array an out-of-bounds situation will occur.
Here's your code slightly revised. In particular, I got rid of the maj_index variable so that the index vs. value mixup cannot happen. I also used a for-each loop for (int current : a) instead of the for-loop for(int i = 0; i < a.length; ++i). Finally, I eliminated the the size parameter (no need to pass it, it can be inferred from the array itself via a.length)
public class MajorityElement {
// 1st condition to check if element is in majority.
public static int findCandidate(int a[]) {
int cand = a[0];
int count = 1;
for (int i = 1; i < a.length; i++) {
if (cand == a[i])
count++;
else
count--;
if (count == 0) {
cand = a[i];
count = 1;
}
}
return cand;
}
public static boolean isMajority(int a[], int cand) {
int count = 0;
for (int current : a) {
if (current == cand)
count++;
}
return count > a.length / 2;
}
private static void printMajority(int a[]) {
int cand = findCandidate(a);
if (isMajority(a, cand))
System.out.printf("%d", cand);
else
System.out.println("no such element as majority");
}
public static void main(String[] args) {
int a[] = { 9, 7, 9, 5, 5, 5, 9, 7, 9, 9, 9, 9, 7 };
printMajority(a);
}
}
Problem is with your :
for(i=1;i<a.length;i++ ){
if(a[maj_index]==a[i])
count++;
else
count--;
if(count==0)
{
maj_index=a[i]; //current element takes max_inex position.
count =1;
}
}
return a[maj_index];
here you are getting the value as like :a[maj_index] for a test data int a[]={2,1,8,8,8,8,6}; the elemnt 8 is the major but a[maj_index] is invalid which is causing the issue,
Instead Complete code can be like below:
public class TestMajor {
/**
* #param args
*/
public static void main(String[] args) {
int a[]={2,1,8,8,8,8,6};
printMajority(a, 7);
}
//1st condition to check if element is in majority.
public static int findCandidate(int a[], int size){
int test = a[0];
int count =1;
int i;
size=a.length;
for(i=1;i<a.length;i++ ){
if(test ==a[i])
count++;
else
count--;
if(count==0)
{
test =a[i]; //current element takes max_inex position.
count =1;
}
}
return test;
}
public static boolean isMajority(int a[], int size, int cand){
int i, count =0;
for(i=0;i<a.length;i++)
{
if(a[i]==cand)
count++;
}
if(count>size/2){
return true;
}
else {
return false;
}
}
private static void printMajority(int a[],int size){
size=a.length;
int cand=findCandidate( a, 7);
if(isMajority(a,size,cand))
System.out.printf("%d",cand);
else
System.out.println("no such element as majority");
}
}
Majority Element in an Array using Java 8 OR Find the element appeared max number of times in an array :
public class MajorityElement {
public static void main(String[] args) {
int[] a = {1,3,4,3,4,3,2,3,3,3,3,3};
List<Integer> list = Arrays.stream(a).boxed().collect(Collectors.toList());
Map<Integer, Long> map = list.parallelStream()
.collect(Collectors.groupingBy(Function.identity(),Collectors.counting()));
System.out.println("Map => " + map);
//{1=1, 2=1, 3=8, 4=2}
map.entrySet()
.stream()
.max(Comparator.comparing(Entry::getValue))//compare the values and get the maximum value
.map(Entry::getKey)// get the key appearing maximum number of times
.ifPresentOrElse(System.out::println,() -> new RuntimeException("no such thing"));
/*
* OUTPUT : Map => {1=1, 2=1, 3=8, 4=2}
* 3
*/
System.out.println("...............");
// A very simple method
//method 2
Integer maxAppearedElement = list.parallelStream().max(Comparator.comparing(Integer::valueOf)).get();
System.out.println(maxAppearedElement);
}//main
}