I'm having a bit of trouble with trying to add an int[] to a List<int[]> while in a recursive method. I'm getting all permutations of an int[] of size N to use with a different function. I want to add each one of these permutations to the previously-mentioned list. However, it doesn't seem that the int[] (shortestPath) can be added for all permutations, and honestly I don't have enough experience with recursion to know why the printouts of each array work, but adding to the List simply adds the first arr (the one passed as the parameter) 6 times.
My code is as follows:
public int counter = 0;
public List<int[]> shortestPaths = new ArrayList<int[]>();
public void permute(int[] arr, int startIndex) {
int size = arr.length;
if (arr.length == (startIndex + 1)) {
System.out.print("Permutation " + counter + " is: ");
for (int i = 0; i < size; i++) {
if (i == (size - 1)) System.out.print(arr[i] + "\n\n");
else System.out.print(arr[i] + ", ");
}
shortestPaths.add(arr);
counter++;
} else {
for (int i = startIndex; i < size; i++) {
int[] copy = arr.clone();
int tmp = copy[i];
copy[i] = copy[startIndex];
copy[startIndex] = tmp;
permute(copy, startIndex + 1);
//tmp = arr[i];
//arr[i] = arr[startIndex];
//arr[startIndex] = tmp;
copy = null;
}
}
}
public static void main(String[] args) {
int[] arr = { 1, 2, 3 };
permute(arr, 0);
System.out.print("\n\n\n\n");
for (int[] a : s.shortestPaths) {
System.out.println(a[0] + ", " + a[1] + ", " + a[2] + "\n\n");
}
P.S. - The printouts are just there for a quick view of the state of the data structures. They will of course be removed when the implementation is fully functional :) Also, this code is nested in a class that has many more functions related to matrix processing. This function in particular is a helper function for a shortest path algorithm.
Thanks in advance to those who know recursion better than I and who are willing to help!
Chris
You are modifying and adding the reference to the same array arr everytime you call add. You should create a new array, swap and then add it to the list.
UPDATE: A little more detail..
You create a new array arr in main, then pass the reference(by value) to the permute function. In the else part, you swap two integers in the array reference arr(you are not creating a new array, just modifying the same one) and add it to the list. Next iteration, the same thing happens with the same array reference arr, adding the same array again to the list.
Here's what you should do instead..
else {
int[] tempArr = new int[arr.length];
System.arraycopy(arr, 0, tempArr, 0, arr.length);
// swap in the tempArr
// add tempArr to the list
// after that if you want you can set tempArr to null, to avoid loitering.
}
There might be a better way, but I'm not an expert either.
Update 2:
Live example.. http://ideone.com/vHcz7b
P.S: Can someone format this for me?
Here are several examples of permutation code that hopefully will help you out
Remember that an array is an object. This means that the parameter arr is a reference to the object. Each recursive call will have a reference to the same array so any changes will be reflected anywhere you use a reference to that array. This also means that each time you call shortestPaths.add(arr); you are adding a reference to the exact same array over and over and over again. So your list will contain many references to the same array object.
With that said, in order to do what you want, you need to make a copy of the array each time you want to make a change and add it to your List.
Related
When I run the below code it's returning same array as output. Can anyone tell me where I am wrong?
public class MoveZeroToend {
public static void main(String[] args) {
int[] arr = { 1, 3, 0, 2, 0, 2, 0 };
Move0Toend(arr);
}
static void Move0Toend(int[] arr) { // Code to move zeroes to end
int count = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] != 0) {
swap(arr[i], arr[count]);
count++;
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " "); // Print the array
}
}
static void swap(int a, int b) { // To swap
a = a + b;
b = a - b;
a = a - b;
}
}
on your swap method, you are not swapping the actual values of the objects you've passed, you are swapping between the values passed to the method but there is no result returned so nothing happens. you need to either do the swap on the actual objects - not in a method, or use another way for this. I would recommend googling "pass by value" and "pass by reference". I would also recommend adding a unit test or at least debug the program so you can validate your code is doing what you want.
Your swap method doesn't return any values, nor does it change the values in the reference of the objects passed. To fix this you can either return two values from your swap method (a and b) or you could do it not in a method, that way it would directly affect the objects.
Just for a little more explanation, the variables a and b in your swap method are local to the swap method, changing these would not affect any other variables, even if they were also named the same, and as your method is a void it can't return anything.
Hope this helps :)
Your swap() method isn't performing any operation on your array, you are just passing two values a and b and swapping them but no operation is being performed on your array.
Instead of passing these two values to your swap() method you can directly swap them inside your for loop as below:
for(int i=0;i<arr.length;i++){
if(arr[i]!=0){
int temp = arr[i];
arr[i] = arr[count];
arr[count] = temp;
count++;
}
}
import java.util.ArrayList;
public class Paaohjelma {
public static int pienin(int[] taulukko) {
int temp, size;
size = taulukko.length;
for(int i = 0; i<size; i++ ){
for(int j = i+1; j<size; j++){
if(taulukko[i]>taulukko[j]){
temp = taulukko[i];
taulukko[i] = taulukko[j];
taulukko[j] = temp;
}
}
}
return taulukko[0];
}
public static int pienimmanIndeksi(int[] taulukko) {
ArrayList<Integer> tauli = new ArrayList<>();
for (int i : taulukko) {
tauli.add(i);
}
return tauli.indexOf(Paaohjelma.pienin(taulukko));
}
public static int pienimmanIndeksiAlkaen(int[] taulukko, int aloitusIndeksi) {
// this methods should get the index of smallest value starting from specified index
int[] tempTauli = taulukko;
tempTauli = new int[tempTauli.length - aloitusIndeksi];
// this gets the right values to temporary array
if (aloitusIndeksi > 0) {
int index = 0;
int indexTauli = 0;
for(int value : taulukko) {
if(index >= aloitusIndeksi) {
tempTauli[indexTauli] = taulukko[index];
indexTauli++;
}
index++;
}
}
// values added are automatically sorted from smallest to largest?
// this shouldn't be, array should be 5, 99, 3, 12 but is shown as 3, 5, 12, 99
for(int inty : tempTauli) {
System.out.println(inty);
}
// get the index of smallest value in array
// index is 0 should be 2
int index = Paaohjelma.pienimmanIndeksi(tempTauli);
// return index of smallest value (add starting index to get the index of smallest value in the original array when starting from specified index)
return index+aloitusIndeksi;
}
public static void main(String[] args) {
// test code
int[] taulukko = {3, 1, 5, 99, 3, 12};
int minIndex = Paaohjelma.pienimmanIndeksi(taulukko);
System.out.println("Pienin: " + Paaohjelma.pienin(taulukko));
System.out.println("Pienimmän indeksi: " + minIndex);
System.out.println(Paaohjelma.pienimmanIndeksiAlkaen(taulukko, 2));
}
}
Hello! I'm doing some programming course work for school and have been stuck in this particular part for couple hours. So I decided it would be best for someone else to take a look and provide some light why my approach for this problem isn't working.
What should happen: class method PienimmanIndeksiAlkaen should return the index of smallest value in provided int array starting from specified index.
The main problem I have been having is that the array seems to be automatically sorting itself and I have no idea what is possible causing this. I have commented the relevant part of the code and would be more than happy if someone could explain why this is happening and what possible could be done to prevent this.
The reason your array is sorted is when you call
System.out.println("Pienin: " + Paaohjelma.pienin(taulukko));
you sort the array.
When you pass the array into this function, you aren't actually passing the value of the array, but the pointer to the array - the address of the array in memory. This is the difference between passing parameters by value or by reference.
How do you know if the value is passed by value or by reference?
As a rule of thumb:
primitive values - i.e. int, double, etc. will be passed by value - their value will be copied and passed to the function.
Any other type, namely arrays and classes, will be passed by reference - the address of the value in memory will be passed to the function, thus any change to the value inside the function will affect it when the function ends too.
Read more here
In array, How do we put new integers in the beginning? I know how to add in the last. But can anyone teach me how to add in the front of the array?
int[]b=new int[a.length+1];
for (int i=0; i<a.length;i++) {
b[i]=a[i];
}
b[a.length]=0;
return b;
For this answer I assume that your ARRAY has a blank box (free position) to spare for the new element. Then it will be very easy.
System.arraycopy(yourArray, 0, yourArray, 1, yourArray.length - 1);
yourArray[0] = newElement;
You don't need a temp array if yourArray can have an additional element. arraycopy() can do all the hardwork of creating temp array, copying values, etc. for you. Make sure BOTH srcPos and destPos are same which is yourArray
Here is the full demo:
public static void main(String[] args) {
int[] yourArray = new int[5];
Arrays.fill(yourArray, 0, 4, 1);
System.out.println("Assume your array looks like this (with additional blank box for new element): " + Arrays.toString(yourArray));
int newElement = 5000;
System.arraycopy(yourArray, 0, yourArray, 1, yourArray.length - 1);
yourArray[0] = newElement;
System.out.println(Arrays.toString(yourArray));
}
If in case you DON'T have any extra space in your array already, you need another array as a placeholder with extra space (finalArray). Instead of having same array in both places, just change destPos to finalArray.
Here is the demo for that:
public static void main(String[] args) {
int[] yourArray = new int[5];
Arrays.fill(yourArray, 0, 5, 1);
System.out.println("Assume your array looks like this (withOUT additional blank box for new element): " + Arrays.toString(yourArray));
int newElement = 5000;
int[] finalArray = new int[yourArray.length + 1];
System.arraycopy(yourArray, 0, finalArray, 1, yourArray.length);
finalArray[0] = newElement;
System.out.println(Arrays.toString(finalArray));
}
If you use an array you can only add elements based on the position. If you want to add a new element to the beginning then you need to shift all other elements one position to the right. Also, keep in mind that you can not change the size of the array.
The sifting would look something like this. N being the position you are placing the new element to.
temp=a[n+1];
for(i=n+1;i>a.length-1;i++)
{
a[i]=a[i+1];
}
a[a.length-1]=temp;
It is almost the same operation, reversed and with a simple trick.
You want to add a new element, so you must create an array big enough to host it, as you did, setting its length as 1 + a.length.
Then you may set the first element to the value you desire to add, I'll write MY_VALUE.
Now you want to fill up the array: this means you have to iterate from index 1 (as 0 has already been filled with MY_VALUE) until we reach b.length - 1.
While iterating, remember that b is bigger than a, plus you're starting with index i = 1, so while this is good for b, you need to adjust it for a, so you'll have to iterate over it "one step less". To do this, you simply have to access all i-1 elements from a, as you can see from the code below.
int[] b = new int[a.length+1];
b[0] = 0;
for (int i = 1; i < b.length; i++) {
b[i] = a[i-1];
}
return b;
You need to create a temporary array ,assign the first position with new element and then copy all the elements in the old array to the new temporary array.
Example:
import java.util.Arrays;
public class Test
{
public static void main(String[] args) {
int[] arrayElements = new int[]{1,2,3,4,5,6,7};
int newElement=0;
int[] tempArr = new int[arrayElements.length + 1];
tempArr[0] = newElement;
System.arraycopy(arrayElements, 0, tempArr, 1, arrayElements.length);
Arrays.stream(tempArr).forEach(System.out::println);
}
}
I already have a list type Integer with values in it and I want to test sequentially from index zero if the sum of one range of elements satisfy a particular value then copy this range in an list and store it in a list of linkedlist. Then again test sequentially but now from the following index of the previous range, so if the previous range was index 0 to index 9 then start at index 10, and repeat the process until the last index.
List<Integer> arrayB = new LinkedList<Integer>(); //this is the array with values in it
List<LinkedList> p = new LinkedList<LinkedList>();// this is the array of arrays
List<Integer> arrayA = new LinkedList<Integer>();// this is the range or the sub list of arrayB
public void function(int n)// suppose that n = 6 and arrayB have these value {1,2,3,1,1,1,1,2}
{
int count = 0;
for (int w : arrayB)
{
count = w + count;
arrayA.add(w);
if(count == n)
{
count = 0;
p.add((LinkedList) arrayA);
arrayA.clear();
}
}
}
However, this code fail when I call method clear in arrayA so is there any alternative to code with this logic regardless of the data structure used?
My understanding of the problem is the following:
There exists an array from which you would like to extract a certain range of values given that they satisfy some criteria. In this case, the criterion is that the range evaluates to some sum. Once this has been completed, you would like to repeat the process until all of the values in the original data-structure have been exhausted.
I will assume that your original data-structure is an array of integers, and that your resulting data-structure is a linkedlist of integer arrays.
One way to do it may be to keep a global counter that keeps track of the current index of the original array, such as something like the following:
int[] originalArray = {//list of numbers separated by commas};
LinkedList<Integer[]> resultingList = new LinkedList<>();
int currentIndex = 0;
public static void function(int totalSum) {
int currentSum = 0;
int initialIndex = currentIndex;
while((currentSum != totalSum) && (currentIndex < (originalArray.length - 1))) {
if(currentSum + initialArray[currentIndex] <= totalSum) {
currentSum += initialArray[currentIndex];
currentIndex++;
}
else {
break;
}
}
if(currentSum = totalSum) {
int[] arrayToAdd = new int[currentIndex - initialIndex - 1];
for(int i = 0; i < currentIndex - initialIndex; i++) {
arrayToAdd[i] = originalArray[initialIndex + i];
}
resultingList.add(arrayToAdd);
}
}
You are using the same list reference arrayA every time you add a sub list into p, every list element in p is pointing to the same arrayA . So when you call arrayA.clear(); You clear all the list elements in p.
To correct that, you need to create a new list object when you add a sublist to arrayA:
public static void function(int n)// suppose that n = 6 and arrayB have these value {1,2,3,1,1,1,1,2}
{
int count = 0;
LinkedList<Integer> subList = new LinkedList<>();
for (int w : arrayB) {
count = w + count;
subList.add(w);
if (count == n) {
count = 0;
p.add((LinkedList) subList); // p is adding a new list reference every time
subList = new LinkedList<>(); // create a new list object, subList points to a new list object
}
}
}
The issue is that when you add your linked list into the final storage p, you are assuming the elements of the list are put in there. Only a pointer is referenced, so when you clear it the next line, all the elements are gone.
p.add((LinkedList) arrayA);
arrayA.clear();
One tip is to move arrayA's scope to inside the function. This is because it's temporary, and only a sublist, so it shouldn't be at the instance level. It can be reused by doing a
arrayA = new LinkedList<Integer>();
and when doing so, you haven't lost the old list because p is keeping a reference to it.
Another tip is to name your lists with meaningful names.
originalIntList, groupedIntList, singleGroupIntList help the reader figure out what they could be doing more than a comment stating obvious aspects of the Java object.
Note:
Following is my homework/assignment, feel free not to answer if you will.
I want to delete/remove an element from an String array(Set) basic, I'm not allowed to use Collections..etc.
Now I have this:
void remove(String newValue) {
for ( int i = 0; i < setElements.length; i++) {
if ( setElements[i] == newValue ) {
setElements[i] = "";
}
}
}
I does what I want as it remove the element from an array but it doesn't shorten the length. The following is the output, basically it remove the element indexed #1.
D:\javaprojects>java SetsDemo
Enter string element to be added
A
You entered A
Set size is: 5
Member elements on index: 0 A
Member elements on index: 1 b
Member elements on index: 2 hello
Member elements on index: 3 world
Member elements on index: 4 six
Set size is: 5
Member elements on index: 0 A
Member elements on index: 1
Member elements on index: 2 hello
Member elements on index: 3 world
Member elements on index: 4 six
You can't change the length of an array object once it's created. Here's an excerpt from JLS 10.2. Array Variables:
Once an array object is created, its length never changes. To make an array variable refer to an array of different length, a reference to a different array must be assigned to the variable.
This means that for this problem, you'd have to allocate a new array that's one-element shorter than the original array, and copy over the remaining elements.
If you need to remove element at index k, and the original array has L elements, then you need to copy over elements (upper bounds are exclusive):
From [0,k) to [0,k) (k elements)
From [k+1,L) to [k,L-1) (L-k-1 elements).
For a total of L-1 elements copied
static String[] removeAt(int k, String[] arr) {
final int L = arr.length;
String[] ret = new String[L - 1];
System.arraycopy(arr, 0, ret, 0, k);
System.arraycopy(arr, k + 1, ret, k, L - k - 1);
return ret;
}
static void print(String[] arr) {
System.out.println(Arrays.toString(arr));
}
public static void main(String[] args) {
String[] arr = { "a", "b", "c", "d", "e" };
print(arr); // prints "[a, b, c, d, e]"
arr = removeAt(0, arr);
print(arr); // prints "[b, c, d, e]"
arr = removeAt(3, arr);
print(arr); // prints "[b, c, d]"
arr = removeAt(1, arr);
print(arr); // prints "[b, d]"
arr = removeAt(0, arr);
arr = removeAt(0, arr);
print(arr); // prints "[]"
}
This uses System.arraycopy; you can always write your own if this isn't allowed.
static void arraycopy(String[] src, int from, String[] dst, int to, int L) {
for (int i = 0; i < L; i++) {
dst[to + i] = src[from + i];
}
}
This is a simplistic implementation that doesn't handle src == dst, but it's sufficient in this case.
See also
In java to remove an element in an array can you set it to null?
Answer: NO!
Note on == for String comparison
Most of the time, using == to compare String objects is a mistake. You should use equals instead.
String ha1 = new String("ha");
String ha2 = new String("ha");
System.out.println(ha1 == ha2); // prints "false"
System.out.println(ha1.equals(ha2)); // prints "true"
See also
Java String.equals versus ==
Difference Between Equals and ==
why equals() method when we have == operator?
The size of an array in Java can't be changed once the array is created. The following links should help you with transferring the existing items to a new array :-)
See: System.arraycopy and Array.copyOf(*).
Basically you need to create a new array which is as long as the old array's length minus 1 and then you need to copy the valid elements from the old to the new array in a loop and then replace the old array with the new array.
Since this is homework, details are left away. Feel free to post a comment for a bit more clarification.
All that setElements[i] = ""; does is change the value of an element in the array. It does not actually remove anything from the array. If you were using a collection class and called remove(i) on it, then you would actually be removing that element from the collection. But here, you're just changing its value. However, arrays in Java have a fixed size and cannot be resized, so there is no way to remove elements from them. The solution, therefore, is to create a new array with a length one shorter than the old one, and then copy all of the values that you want to keep into the new one. So,
Create new array with a length of setElements.length - 1.
Copy all of the elements in setElements into the new array, except for the one which you're looking to remove. Be careful of the fact that the indices into the two arrays will be off by one rather than equal once you've reached the index for the element that you wish to remove.
Set setElements to the new array if you want to keep using the same variable for your array.
void remove(String newValue) {
if(setElements.length == 0) return;
String [] array = new String[setElements.length-1];
int j = 0;
for ( int i = 0; i < setElements.length; i++) {
if ( setElements[i] != newValue ) {
array[j++] = setElements[i];
}
}
setElements = array;
}