I am trying to write a recursive bubble sort method but I get ArrayIndexOutOfBoundsException: 11. I cannot see what I did wrong.
public static int[] recBubSort(int []arr, int n){
if(n > arr.length-1){
return arr;
}
if(arr[n] > arr[n+1]){
swap(arr,n,n+1);
}
return recBubSort(arr,n+1);
}
public static void swap(int arr[], int minPos, int index) {
//System.out.println("SelectionSort SWAP...");
int temp = arr[minPos];
arr[minPos] = arr[index];
arr[index] = temp;
}
You checked that n is not greater than the last allowed index (which is length - 1, but then in your next if, you ask about arr[n+1].
Suppose your array has 5 items. And your n is 4. You checked it and it is not greater than 5-1. But n+1 is 5, and there is no item #5.
It's this line:
if(arr[n] > arr[n+1]){
You aren't checking if n+1 is out of bounds. You only check if n is out of bounds.
ArrayIndexOutOfBoundsException mean The index is either negative or greater than or equal to the size of the array.
you can try this..
void bubbleSort (double array[], int size)
{
double temp ;
for (int pass = 1; pass < size; pass++)
for (int i = 0; i < size – pass; i++)
if (array [i] > array [i+1])
{
temp = array[i] ;
array[i] = array [i+1] ;
array [i+1] = temp ;
}
}
Related
I have made this code to rotate an array by k times. In this when I'm adding i=0 , it is showing an "ArrayOutOfBounds" exception, and when I'm changing the value of i by 1, it is showing wrong output. Why is it showing this exception? And is there any way I could correct this code?
public void rotate(int[] nums, int k)
{ int j=0, temp=0;
for(j=0;j<k;j++)
{
for(int i=0;i<nums.length;i++)
{
temp=nums[i-1];
nums[i-1]=nums[i];
nums[i]=temp;
}
}
}
}
At i=0 you are trying to access nums[i-1] = num[-1] which is an invalid position and hence an ArrayOutOfBound exception is thrown.
So, the modified version would be:
for (j=0; j<k; j++)
{
for (int i=1;i<nums.length;i++)
{
temp=nums[i-1];
nums[i-1]=nums[i];
nums[i]=temp;
}
}
But the above will rotate the array by k times towards the left not right as you are shifting the elements towards the left. So, to get the right rotation you need to shift the elements from the end of the array. Like:
for (j=0; j<k; j++)
{
for (int i=nums.length-1; 0<i; i--)
{
// shifting towards the right
temp=nums[i-1];
nums[i-1]=nums[i];
nums[i]=temp;
}
}
Edit (from comments above): If i is 0, you're trying to get an index of -1 which will raise an ArrayOutOfBounds exception. If i starts from 1, then you're not dealing with the first number.
Here's the function you can use to rotate integers to the right:
public void rotate(int[] nums, int k) {
int arrLen = nums.length;
// If the number of times you want to rotate is bigger than the size of the array, get the minimum number of rotations to get the same result.
while (k > n) {
k = k - arrLen;
}
k = arrLen - k;
k = k % arrLen;
int i, m, n, temp;
int g_c_d = gcd(k, arrLen);
// Move the value in the i-th index
for (i = 0; i < g_c_d; i++) {
temp = arr[i];
m = i;
while (true) {
n = m + k;
if (n >= arrLen) {
n = n - arrLen;
}
if (n == i) {
break;
}
arr[m] = arr[n];
m = n;
}
arr[m] = temp;
}
}
// Find the greatest common divisor of two numbers, a and b
public void gcd(int a, int b) {
if (b == 0) {
return a;
} else {
return gcd(b, a % b);
}
}
Let me briefly explain what it does. This is one of the most known algorithms: juggling. You divide the array into the n number of sets where n denotes the greatest common divisor of the length of the array and the number of times you want to rotate. Then, you move the numbers within sets.
This might be the most efficient in terms of time (as its time complexity is O(n)).
A better solution would be taking a copy of the given array with the values '0' then looping through the given array to obtain a new_index.
Formula for the New_index for the Clock-wise rotating array:
for(int i=0;i<nums.length;i++){
int new_index = (old_index+k)%(a.length)
copy[new_index] = a[old_index]
}
Now the entire function code would be:
public static void rotate(int[] a, int k)
{
int n = a.length;
int[] copy = new int[n];
// fill the values with zeroes
for(int i=0;i<n;i++){
copy[i]=0;
}
// rotate the array
for(int i=0;i<n;i++){
int new_index = (i+k)%n;
copy[new_index] = a[i];
}
// Now that the array is copied, copy the elements to the original array. Because they asked to rotate the given array.
for(int i=0;i<n;i++){
a[i]=copy[i];
}
}
function solution(arr, k) {
if(k == 0) return arr;
if(arr.length == k) return arr;
if(arr !== undefined && arr !== null){
let counter = k > arr.length ? k % arr.length : k;
let rotArray = [];
rotArray = arr.slice(arr.length - counter, arr.length).concat(arr.slice(0,arr.length - counter))
return rotArray;
}
return arr;
}
When I create this method to find the index of the smallest number in an array starting from a specific index, it keeps returning 0 no matter which numbers are in the array. It seems that index = i in the for loop is not updating the value of the index variable, even if the array contains other numbers lower than the 0 spot. Why?
public static int indexOfSmallestFrom(int[] array, int startIndex) {
int smallest = array[startIndex];
int index = 0;
for (int i = startIndex; i < array.length; i++) {
int each = array[i];
if (each < smallest) {
smallest = each;
index = i;
}
}
return index;
}
edit: Here's the main method:
public static void main(String[] args) {
// write your test code here
int[] array = {99, 3, 1, 7, 4, 5, 2, 4};
System.out.println("Smallest: " + indexOfSmallestFrom(array, 1));
}
It works correctly every time EXCEPT when the startIndex variable passed to the method call is 2! When a 1 is passed as above, it correctly returns 2, when 3 is passed, it correctly returns 6, etc. ???
Because when you pass startIndex = 2 into the function, we have smallest = array[startIndex] = 1 in this case, and your code initializes int index = 0;. However, in your for loop, you have:
for (int i = startIndex; i < array.length; i++) {
int each = array[i];
if (each < smallest) {
smallest = each;
index = i;
}
}
Since your smallest was initialized to the number at position startIndex but not your index, and the fact that startIndex happened to be the index of the smallest number, your if (each < smallest) will never be entered, meaning that index will stay at 0.
To fix this, either change int index = 0; to int index = startIndex; OR you can change the condition in the if statement to if (each <= smallest) and your code should work fine (note that if you do this, it will return the last index if multiple minimums are present in the array).
Your code works for me, may be the smallest value is in 0 place in your case. But you should change index = startingIndex. Because that is where you are comparing items from.
public static int indexOfSmallestFrom(int[] array, int startIndex) {
int smallest = array[startIndex];
int index = startIndex;
for (int i = startIndex; i < array.length; i++) {
int each = array[i];
if (each < smallest) {
smallest = each;
index = i;
}
}
return index;
}
Or change < to <=
public static int indexOfSmallestFrom(int[] array, int startIndex) {
int smallest = array[startIndex];
int index = 0;
for (int i = startIndex; i < array.length; i++) {
int each = array[i];
if (each <= smallest) {
smallest = each;
index = i;
}
}
return index;
}
Because the value in position 2 is the SMALLEST value (it's 1), hence the if condition is never entered :).
I am writing code to sort an array in order. I checked some algorithm for sort and merge, however I found that if I just go through the array and compare every 2 elements and swap them and repeat that until the array is sorted.
So if array[I] > array[i++], swap, repeat.
It is not working so far. I also need a break point to avoid stack overflow: I need some help please
Array:
int[] newArray = new int[] {3,9,5,7,4,6,1};
SortArray s = new SortArray();
s.sortThisArray(newArray, 0, 0);
Recursive function:
public String sortThisArray(int[] array, double counter, double a)
{
int swap0 = 0;
int swap1 = 0;
if (a > 1000)
{
return "reached the end" ;
}
for (int i =0; i<array.length; i++)
{
if (array[i] > array[i++])
{
swap0 = array[i];
swap1 = array[i++];
array[i++] = swap0;
array[i] = swap1;
counter = counter++;
a = array.length * counter;
sortThisArray (array, counter, a);
}
}
for (int j = 0; j<array.length ; j++)
{
System.out.println(array[j]);
}
return "completed";
}
}
What you are searching for is recursive bubble sort algorithm.
The main error is confusing i++ (which increments i every time) with i+1, that is only the position in the array after i, without incrementing. Then, there is no need to use double for counter, and also the a variable is not needed. You need only the length of the current segment, this way:
import java.util.*;
public class RecursiveBubbleSort {
public static void main(String[] args) throws Exception {
int[] newArray = new int[] {3,9,5,7,4,6,1};
sortThisArray(newArray, newArray.length);
System.out.println("Sorted array : ");
System.out.println(Arrays.toString(newArray));
}
public static int[] sortThisArray(int[] array, int n) {
if (n == 1) {
return array; //finished sorting
}
int temp;
for (int i = 0; i < n-1; i++) {
if (array[i+1] < array[i]) {
temp = array[i];
array[i] = array[i+1];
array[i+1] = temp;
}
}
return sortThisArray(array, n-1);
}
}
The ++ operator evalutes separately. So in the case i++, we will read i and then increment it by 1. And the other way around, ++i, would first apply the increment to i, and then read i. So when you want to check for the next element in the array, [i+1] is what you are looking for. With the same reasoning, can you figure out whats wrong with this line?
counter = counter++;
And do we even need it?
public static int[] sortArray(int[] arr) {
Arrays.sort(arr);
return arr;
}
public static int findElement(int[] arr, int x) {
int start = 0;
int end = arr.length;
int mid = 0;
while (start <= end) {
mid = (start + end)/2;
if (arr[mid] == x) {
return x;
}
else if (x <= arr[mid]) {
end = mid - 1;
}
else {
start = mid + 1;
}
}
return mid;
}
public static void printKclosest(int arr[], int x, int k)
{
int element = findElement(arr, x);
int count = 0;
for (int i = 0; i < arr.length; i++) {
int difference = Math.abs(arr[i] - element);
while (count < k) {
if (difference > 0) {
System.out.println(arr[i]);
count++;
}
}
}
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
int[] array = {-1, 3, 5, 2, 1, 7};
sortArray(array);
System.out.println(Arrays.toString(array));
printKclosest(array, 2, 3);
}
}
for find the k nearest elements, i was thinking I could use a for loop to go through each element in the array and subtract from the element that's X and print the number of k elements that have the smallest difference, but the output I'm getting is -1 k amount of times.
function findElement returns x value if x exists but index of potential place for x if it does not present in array.
So in the second case your comparison int difference = Math.abs(arr[i] - element); has no sense
How to overcome: change in findElement
int end = arr.length - 1;
return x;
to
return mid;
and
difference = Math.abs(arr[i] - arr[element]);
But approach to get k closest numbers is completely wrong. Suggestion:
Set L index to element and R index to element+1
Compare abs differences for L and R. Output smaller. If smaller is for R, decrement L, otherwise increment R. Repeat k times (don't forget about array range)
In addition to MBo's great suggestion for outputting the k closest elements using L and R pointers, you could also solve this without sorting the array in O(n log k) time by iterating over the array once and keeping the chosen elements in a heap, each time removing the farthest (k+1)th element.
For this assignment, I am unable to get the last method to loop again and find the next largest element in the series of random numbers. Some input to solve this problem would be great. Thank you.
public static void main(String[] args) {
int[] array = randomIntArray (10);
sortArray (array);
}
public static int randomInt (int low, int high){ // Create a serie of random numbers
int x = 0;
for (int i = 0; i < 10; i++){
x = (int)(Math.random ()* (high - low) +low);
}
return x;
}
public static int[] randomIntArray (int n) { // Size of array
int[] a = new int [n];
for (int i = 0; i <a.length; i++){
a[i] = randomInt (-5, 15);
}
return a;
}
public static int indexOfMaxInRange (int[] a, int low , int high){
int index = low;
for (int i = low +1; i < high; i++){
if (a[i] > a[index]){ // If the position of i is greater than index
index = i; // then index will equal that position with the highest element
}
}
return index;
}
public static int swapElement (int []a, int index , int i){
int tmp =0;
for(i = 0; i < (a.length); i++) {
tmp = index;
a[i]= a[tmp] ;
}
return a[tmp] ;
}
public static void sortArray (int[] array){ //The sortArray calls the indexOfMaxInRange to get the index of the largest element, then uses swapElement to swap that index's position to position a[i].
for (int b= 0; b <array.length; b++){
System.out.println (array[b]+"\t"+ b); // Print out original list of random numbers
}
System.out.println ();
for (int i = 0; i <array.length; i++){
int index = indexOfMaxInRange (array, 0, 10 );
int sort = swapElement (array, index, 0);
System.out.println (sort+"\t"+ i);
}
}
This looks like homework, since sorting an array is handled by umpteen available libraries, so I am going to try to give hints rather than a full answer.
Your randomInt function does 10 times more work than it needs to. This won't change the behavior of your program but it's a waste.
Your swapElement function doesn't look at all right. You don't need to return anything, and you don't need to loop. Just swap the elements in positions "index" and "i". Maybe call the arguments "a" and "b" or "pos1" and "pos2" to be less confusing.
Inside sortArray, after you find the largest element and put it in position 0, you need to keep going and find the 2nd largest element and put it in position 1, and so forth. You will need to have a loop for this. You have the pieces almost ready. Hint: you can find the 2nd largest element, after you've put the largest one in position 0, by finding the largest remaining element (i.e. call indexOfMaxInRange but pass 1 as the start position).
Changes made to the last 3 methods
public static int indexOfMaxInRange (int[] a, int low , int high){
int index = low;
for (int i = low +1; i < a.length; i++){
if (a[i] > a[index]){ // If the position of i is greater than index
index = i; // then index will equal that position with the highest element
}
}
return index;
}
public static void swapElement (int []a, int index , int i){
int pos2;
pos2 = index;
a[i]= a[pos2];
System.out.println (a[i]+"\t"+ index);
}
public static void sortArray (int[] array){
for (int b= 0; b <array.length; b++){
System.out.println (array[b]+"\t"+ b);
}
System.out.println ("Number in order");
for (int i = 0; i <array.length-1; i++){
int index = indexOfMaxInRange (array, i, 10 );
swapElement (array, index,i );
}
}