public static void moveRight (int a[], int n){
int aux;
for(int i = 1; i<n; i--){
aux = a[i];
a[i]= a [i];
}
}
I been trying with this code but it doesn't work.
When printing the contents of an array, the left starts with the lowest values. If you move the values down the indexes you could say this is to the left. For moving the values up by index you need to start at the end and work down.
// Move one up
for (int i = a.length - 1; i > 0; i--)
a[i] = a[i-1];
// Move one down
for (int i = 0; i < a.length-1; i++)
a[i] = a[i+1];
Note: This is likely to be inefficent compare with using arraycopy which is designed for bulk array copies.
// Move one up
System.arraycopy(a, 0, a, 1, a.length-1);
// Move one down
System.arraycopy(a, 1, a, 0, a.length-1);
First, the loop variable is supposed to be going up. so change i-- to i++. Then, if I correctly understand what you're trying to do, you need a[i] = a[i-1] in the loop body. instead of a[i] = a[i] (which does nothing). Also, you don't need aux.
It's not clear what, if anything, you want to happen to a[0] when everything moves to the right. That should take place after the loop exits. (If you want the last element to move to the first element position, then I retract my comment about tmp; you'll need to store that last element somewhere so it's available after the array element gets overwritten. But it only needs to be stashed once, before the loop starts.)
One other comment: n must never be more than a.length or the loop will throw an exception. If n is always equal to a.length, then you can dispense with the argument and just use a.length in the method.
Related
First I created a random array then I decided to create another array to save the number except the highest. I got the prob when printing the array removed the highest number. I assume the issue when assigning item in b but I can't figure out. Please help :<
public static int[] deleteHighestNum(int a[]) {
int b[] = new int[a.length - 1];
for (int i = 0, j = 0; i < a.length; i++) {
if (a[i] > a[j]) {
b[j++] = a[j];
}
}
return b;
you first create a copy of the array with the .clone() method. This will be the second array you created. then you create an int x or something of this sort and set it equal to 0.
start now by iterating the array. if the number is greater then your int, replace the int.
once it is done, make another loop, that checks each value of your second array and if a number is equal to your int, delete it. done.
I've been at this for a couple days, reading many pseudocode and watching videos to explain recursion and mergesort. I understand mergesort and somewhat understand recursion -- except for when it applies to arrays as is in my code below. I did some debugging and it appears that my program is not sorting correctly regardless of the out of bounds error. I am very lost and would appreciate any help you can offer!
Questions:
1) what does it mean for a recursion on an array? Does it create a sub array that is held by the original array? -- if that makes sense.
2) why is my code running into a out of bounds error even though I followed a tutorial to the t and also set the k value after every pass. Specifically the issue is being encountered.
Here's the code:
public class Merge {
public static void main(String[] args) {
}
static void mergeSort(int arr[]){
int r = arr.length - 1;
Merge.sort(arr,0,r);
System.out.println(arr);
}
static void sort(int arr[], int p, int r){
if(p<r){
int q = (p+r)/2;
sort(arr,p,q);
sort(arr,q+1,r);
merge(arr,p,q,r);
}
}
static void merge(int arr[], int p, int q, int r){
int n1 = q-p+1;
int n2 = r-q;
int L[] = new int[n1];
int R[] = new int[n2];
for(int i = 0; i< n1; i++){
L[i] = arr[i];
}
for(int j = 0; j< n2; j++){
R[j] = arr[q+1+j];
}
int i = 0, j = 0;
int k = 1;
while(i<n1 && j<n2){
if(L[i]<= R[j]){
arr[k] = L[i];
i++;
}
else{
arr[k] = R[j];
j++;
}
k++;
}
while(i<n1){
arr[k] = L[i];
i++;
k++;
}
Error occurs here --> while(j<n2){
arr[k] = R[j];
k++;
}
}
}
Thank you for the help!
edit: Just wanted to say how greatful I am for the amazing replies on this post, thank you so much for your time.
To be honest I don't think your sentence 'recursion on an array' makes any sense.
Your code has one array arr which gets sorted. Your merge method is supposed to be sorting parts of this array, but every time it is called it has the same whole array object. There are no sub-arrays; it's just up to this method to sort the relevant part of this one array. If this method isn't doing what it's supposed to do, then problems will occur.
Let's take a closer look at the loop where you are getting an error:
while(j<n2){
arr[k] = R[j];
k++;
}
Suppose we get to this loop with j < n2. What happens?
We enter the loop because j < n2, so we copy R[j] to arr[k] and then increment k. We go back to the top of the loop, we find j is still less than n2 because neither variable has changed, so we copy R[j] to arr[k] and increment k again. We got back to the top of the loop, find j is still less than n2 and go round again. And so on, and so on, until eventually k falls off the end of arr and we get an ArrayIndexOutOfBoundsException.
In this part of mergesort we are trying to copy into arr the contents of R that haven't already been merged into arr, but we forgot to increment j. So, to fix this loop, increment j as well as k:
while(j<n2){
arr[k] = R[j];
j++;
k++;
}
Note that the previous loop, the one beginning with while(i<n1), increments i and k. This change now makes the two loops look more similar to one another.
So, we run our code again, and what happens? We still get an ArrayIndexOutOfBoundsException. Clearly we haven't solved the problem yet, but have we made any progress at all if we're just getting the same error?
The intention of the merge method is to merge the subarrays of arr from positions p to q inclusive and from positions q+1 to r inclusive. If the two subarrays are sorted, then after merging the whole subarray of arr from p to r will be sorted.
However, when we write the values back into arr, we start at index 1. Is this correct? Suppose arr has length 2, p = 0, q = 0 and r = 1. We have two elements to sort. Where does the first one get written to, and where does the second?
The answer is the first one gets written to arr[1], and your code throws an exception because it attempts to write the second to arr[2], which does not exist.
You want k to start from the start of the subarray you are sorting. You want k to start from p.
So replace the line
int k = 1;
with
int k = p;
We try again, and now we find the code no longer throws an exception but prints something unintelligible like [I#65fb1cd. Annoyingly, this is how Java prints arrays by default. To fix this, add the line import java.util.Arrays; to your file and replace the line
System.out.println(arr);
with
System.out.println(Arrays.toString(arr));
Your code should now print out a list of numbers when it runs.
However, we now see that our code isn't sorting the array correctly. I asked it to sort the values 8, 1, 4, 9 and it came back with 1, 1, 8, 9. The 1 has been duplicated and the 4 has disappeared.
Recall once again that the intention of the merge method is to sort arr from p to r onwards. Take a careful look at what values are being copied from the array into L and R:
for(int i = 0; i< n1; i++){
L[i] = arr[i];
}
for(int j = 0; j< n2; j++){
R[j] = arr[q+1+j];
}
Notice any difference between these two loops, apart from the fact that one uses j instead of i, n2 instead of n1 and R instead of L?
Note that when you copy into R, you are copying values from position q+1 onwards. These are the values in the second sorted subarray. But when you are copying into L, you are copying values from position 0 onwards. This isn't necessarily where the first sorted subarray begins. That of course starts from p.
Replace the first of these loops with:
for(int i = 0; i< n1; i++){
L[i] = arr[p+i];
}
Finally, we run the code and find that we now have a working mergesort program.
Let's break your question down a bit - specifically, what does recursion mean? You can think of it like a loop - it performs an operation on itself until it reaches a stop condition. Take for example, a for loop
for(int i = 0; i < 2; i++)
will perform the operation until it reaches the case where variable i is no longer less than 2. Likewise, recursively
void methodLoop(int input){
int i = input;
if(i < 2){
methodLoop(i+1);
}
else{
System.out.println("Base case reached! I is no longer less than 2!");
}
}
Performs a similar operation, just with recursion instead!
What does this mean for arrays? It depends. What you've touched upon in your question is a concept called multidimentional arrays - arrays within arrays. These work like normal arrays, it's just an array that contains another array in each one of its indexes - these are instantiated as follows
String[][] multidimensionalarray = new array[4][4]
To visualize such a concept, it might be easier to think of it as a coordinate grid, with the indexes being the coordinate places and the value at that index containing information about that place. For example, assuming the multidimensional array has been filled with data like so, it might look like:
4 a b c d
3 e f g h
2 i j k l
1 m n o p
1 2 3 4
and then the value of multidimensionarray[2][3] would return the string k!
// gives next index in array which wraps around in a ring; moves clockwise through indices
private int nextSlot(int k) {
return ((k + 1) % A.length);
}
// Insert method
public void insert(int k) {
if( size == A.length)
resize();
A[next] = k;
for(int i = 0; i < next; i = nextSlot(i)) {
if(k < A[i]) {
for( int j = next - 1; j >= i; j--){
A[nextSlot(j)] = A[j];
}
A[i] = k;
break;
}
}
next = nextSlot(next);
size++;
}
I am trying to create an insert/sort method that inserts values into a circular priority queue in ascending order. The problem I'm having is when the next pointer cycles back to the beginning of the array, the items at the front of the queue aren't being sorted. I've been struggling with this for hours now, any help would be greatly appreciated.
Specifically, when next cycles back to the beginning, it's going to be 0, and therefore this for loop:
for(int i = 0; i < next; i = nextSlot(i)) {
will not do anything.
In general, however, I see several problems with your program. First of all, why are you implementing this as a circular array? Circular arrays are useful when you want to be able to quickly add/remove from both the beginning and end of an array. You seem to be inserting into the middle, so there is no reason to complicate your code when you're doing a linear search through the entire list at each insert anyway.
Finally, be aware that when operating on a circular array, you need to take into account that your indices will wrap around and become 0. Therefore, this line:
for( int j = next - 1; j >= i; j--)
is wrong for at least two reasons:
j>=i is not the correct way to find out if j has reached i
j-- is also wrong as j-1 needs to be wrapped
I'm practicing what are pretty basic java array exercises and I'm having a hard time wrapping my head around how to insert an element into the beginning of an array and then shift the remaining elements to the right. So if the array hasn't gone over its max size, inserting a z in front of array, j, a, v, a would make for z, j, a, v, a.
I know how to do this with array lists, I'm just having a difficult time getting the logic correct with arrays. This is what I have so far:
public void addFront(char ch)
{
for(int i = 1; i < data.length-1; i++){
char temp = data[i - 1];
data[i] = temp;
}
data[0] = ch;
}
It seems like I need a temporary variable but I'm not using it correctly in this instance. Any input would be appreciated!
Let's take a look at what your current loop is doing. It is copying the character from position i - 1 to the current position. But the next loop will copy it from (current) i to (current) i + 1. It will just copy the first character over every position in the array except for the last position.
You must iterate backwards through the array, so that one shift doesn't accidentally use the result of the previous shift.
Start at index data.length - 1, and copy from position i - 1 to position i, making sure that the last iteration is when i is 1.
Additionally, a temp variable isn't needed. You can copy the value directly, i.e.
data[i] = data[i - 1];
Start at the back end of the array.
If you move element 0 to element 1, then element 1 to element 2... well you already copied element 0 to element 1.... so now you'll just copy element 0 over the entire array.
Start at the back end of the array shifting everything to the right, then after you're done with that, insert the new element at the front.
public void addFront(char ch) {
for(int i = data.length-1; i > 0; --i) {
data[i] = data[i-1];
}
data[0] = ch;
}
You don't need a temporary variable for an insert, as described this should work...
public void addFront(char ch)
{
for(int i = data.length - 1; i > 0; i--){ // start at the end.
data[i] = data[i-1]; // move every element up 1... that is set the current
// element to the prior element.
}
for (int i = data.length - 1; i >= 0; i--) {
if (data[i] == null) { // find the first blank...
data[i] = ch; // set the initial value.
break;
}
}
}
// A strange variation on a bubblesort I created inadvertently. I omitted the usual if a[j] >a[j+1] by mistake yet the code was still able to function perfectly. Would there be any advantage to using a bubblesort of this kind over a normal bubblesort.
public int[] bubbleSort(int[] a)
{
for (int i = 0; i < a.length - 1; i++)
{
for (int j = i + 1; j < a.length - 1; j++)
{
if (a[i] > a[j])
{
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
return a;
}
Notice that at the end of the first iteration of the outer loop, the first value in the array will necessarily be the minimum value in the array (do you see why?) After the second iteration, the second value will be the second-smallest value, and after the third iteration the third value will be the third-smallest value, etc.
(That said, I think there's a bug in your logic. The upper bound on j should be a.length rather than a.length - 1, since otherwise the last value in the array is never compared to anything else or moved.)
You might want to look into selection sort, which works by moving the smallest value in the array to the front, then the second-smallest, etc. The algorithm you've come up with is (essentially) a modified version of selection sort rather than a modified bubble sort.
Hope this helps!