Pushing Integer array to ArrayList - java

I got stuck in very basic way of pushing sequence of Integer-array to arraylist.
I am trying alter the solution of polygenelubricants for the question K Combinations of set of Integers such that instead of printing them, I am pushing them to an array list.
My code:
public class Test {
static ArrayList<String> combinations;
public static void main(String args[]) {
Integer[] a3 = { 1, 2, 3, 4, 5 };
comb(a3, 2);
}
public static void comb(Integer[] items, int k) {
Arrays.sort(items);
combinations = new ArrayList<String>();
ArrayList<String> c1 = new ArrayList<String>();
c1 = kcomb(items, 0, k, new Integer[k]);
System.out.println("from comb");
for (String x : c1) {
System.out.println(x);
}
}
public static ArrayList<String> kcomb(Integer[] items, int n, int k,
Integer[] arr) {
if (k == 0) {
combinations.add(Arrays.toString(arr));
} else {
for (int i = n; i <= items.length - k; i++) {
arr[arr.length - k] = items[i];
kcomb(items, i + 1, k - 1, arr);
}
}
return combinations;
}
}
Output:
from comb
[1, 2]
[1, 3]
[1, 4]
[1, 5]
[2, 3]
[2, 4]
[2, 5]
[3, 4]
[3, 5]
[4, 5]
But When I changed the type of ArrayList from String to Integer[] as follows, I am getting redundant output.
Changed Code
public class Test {
static ArrayList<Integer[]> combinations;
public static void main(String args[]) {
Integer[] a3 = { 1, 2, 3, 4, 5 };
comb(a3, 2);
}
public static void comb(Integer[] items, int k) {
Arrays.sort(items);
combinations = new ArrayList<Integer[]>();
ArrayList<Integer[]> c1 = new ArrayList<Integer[]>();
c1 = kcomb(items, 0, k, new Integer[k]);
System.out.println("from comb");
for (Integer[] x : c1) {
System.out.println(Arrays.toString(x));
}
}
public static ArrayList<Integer[]> kcomb(Integer[] items, int n, int k,
Integer[] arr) {
if (k == 0) {
combinations.add(arr);
} else {
for (int i = n; i <= items.length - k; i++) {
arr[arr.length - k] = items[i];
kcomb(items, i + 1, k - 1, arr);
}
}
return combinations;
}
}
Output:
from comb
[4, 5]
[4, 5]
[4, 5]
[4, 5]
[4, 5]
[4, 5]
[4, 5]
[4, 5]
[4, 5]
[4, 5]
Can someone help me to point out what am I doing wrong...
Thanks,
Sarath

public class Test {
static ArrayList<Integer[]> combinations;
public static void main(String args[]) {
Integer[] a3 = { 1, 2, 3, 4, 5 };
comb(a3, 2);
}
public static void comb(Integer[] items, int k) {
Arrays.sort(items);
combinations = new ArrayList<Integer[]>();
ArrayList<Integer[]> c1 = new ArrayList<Integer[]>();
c1 = kcomb(items, 0, k, new Integer[k]);
System.out.println("from comb");
for (Integer[] x : c1) {
System.out.println(Arrays.toString(x));
}
}
public static ArrayList<Integer[]> kcomb(Integer[] items, int n, int k,
Integer[] arr) {
if (k == 0) {
combinations.add(arr);
} else {
for (int i = n; i <= items.length - k; i++) {
Integer[] arr1 = new Integer[arr.length];
System.arraycopy(arr, 0, arr1, 0, arr.length);
arr1[arr.length - k] = items[i];
kcomb(items, i + 1, k - 1, arr1);
}
}
return combinations;
}
}

There is your error: combinations.add(arr); you are working always on the same array arr.
Keep in mind, arrays are objects and have a reference. You save the same array arr reference to the ArrayList and keep changing the array values afterwards. You always get the value of the last combination for all other combinations as you are working on the same array every time.
Therefore, you need to clone arr before you add it to the ArrayList in order to obtain a new reference. The code was working before as every String has its own reference as Strings are immutable.

the problem is that you are only ever creating one Integer[] array - it is being reused for each call to kcomb, so at the end of the process the same array has been added multiple times to the list, but the contents of the array is only the last combination. Also, you don't need to use Integer[] for this purpose - int[] is quite satisfactory and more efficient.

Related

Remove an element from array and replace with 0?

public static void remove (int[] arr, int toRemove)
"It should remove the value toRemove from the array. The remaining elements should just be shifted toward the beginning of the array. (The array's size will not change). Since the array will now have one fewer element in use, the original last element should just be replaced with 0. If there is more than one occurrence of toRemove in the array, only the FIRST occurrence should be removed. If the array has no elements, it should just have no effect".
So far, I have this:
public static void remove(int[] arr, int toRemove) {
for(int i = 0; i <= arr.length - 1; i++) {
if(arr[i] == toRemove) {
arr[i] = arr[i + 1];
arr[toRemove] = 0;
}
}
}
I have a main method with an array with its contents: [3, 5, 7, 8, 12, 2] and a call saying remove(array, 5). However, my array prints out [3, 7, 7, 8, 12, 0], when it should print out [3, 7, 8, 12, 2, 0].
Can someone let me know what I have wrong and explain it?
Here is an approach, similar to what I described in the comments above.
import java.util.Arrays;
public class main
{
// tip: arguments are passed via the field below this editor
public static void main(String[] args)
{
int[] arr = {3, 5, 7, 8, 5, 12, 2};
remove(arr, 5);
System.out.println(Arrays.toString(arr)); // [3, 7, 8, 5, 12, 2, 0]
}
public static void remove(int[] arr, int toRemove) {
int idx = -1;
// determine first occurrence of toRemove
for(int i = 0; i < arr.length; i++) {
if(arr[i] == toRemove) {
idx = i;
break;
}
}
// if not found, return
if(idx == -1) return;
// shift other elements down
for(int i = idx; i < arr.length-1; i++) {
arr[i] = arr[i+1];
}
// set last element to 0
arr[arr.length-1] = 0;
}
}
You need to have two indexes:
fromIndex is the one that go on the array.
toIndex is the place that the item need to be.
public static void remove(int[] arr, int toRemove) {
int toIndex = 0;
for(int fromIndex = 0; fromIndex < arr.length; fromIndex++) {
//paste number only if its not 'toRemove'
if(arr[fromIndex] != toRemove) {
arr[toIndex] = arr[fromIndex];
toIndex++;
}
}
//Fill the rest with 0
for (; toIndex < arr.length; toIndex++)
arr[toIndex] = 0;
}
this works if there are multiple indexes with the value of toRemove
You should use System.arraycopy. It's fast.
Try this.
public static void remove(int[] arr, int toRemove) {
for(int i = 0, length = arr.length; i < length; i++) {
if(arr[i] == toRemove) {
System.arraycopy(arr, i + 1, arr, i, length - i - 1);
arr[length - 1] = 0;
break;
}
}
}
public static void main(String[] args) throws IOException {
int[] a0 = {0, 1, 2, 3, 4};
remove(a0, 0);
System.out.println(Arrays.toString(a0));
int[] a4 = {0, 1, 2, 3, 4};
remove(a4, 4);
System.out.println(Arrays.toString(a4));
int[] a5 = {0, 1, 2, 3, 4};
remove(a5, 5);
System.out.println(Arrays.toString(a5));
int[] a6 = {0};
remove(a6, 0);
System.out.println(Arrays.toString(a6));
int[] a7 = {};
remove(a7, 0);
System.out.println(Arrays.toString(a7));
}
output:
[1, 2, 3, 4, 0]
[0, 1, 2, 3, 0]
[0, 1, 2, 3, 4]
[0]
[]

Avoid repeating arrays in random permutations in java

I have the following code:
public static void nextPermutationArray(int[] v) {
int x = 1;
int y;
Random r = new Random();
while (x < v.length) {
y = x + r.nextInt(v.length - x);
int temp = v[x];
v[x] = v[y];
v[y] = temp;
x++;
}
}
public static void main(String[] args) {
int[] a = new int[]{0, 1, 2, 3};
nextPermutationArray(a);
System.out.println(Arrays.toString(a));
nextPermutationArray(a);
System.out.println(Arrays.toString(a));
nextPermutationArray(a);
System.out.println(Arrays.toString(a));
nextPermutationArray(a);
System.out.println(Arrays.toString(a));
}
The program returns me:
0321
0231
0231
0132
My question is: is there any way to edit the method nextPermutationArray to avoid random permutations like 0231. In other words, the method should return 4 unrepeatable elements.
You can store each permutation that has already been returned in a static variable of type int[][]. If you get a result that is already in the array, you can make another permutation. Repeat until you have a new permutation. But be careful, this can make an endless loop if you want to produce more permutations than possible!
This should print out all the permutation without storing them in a HashMap or a List
public static boolean nextPermutationArray(int[] a) {
int i = a.length - 2;
while (i >= 0 && a[i] >= a[i + 1]) {
i--;
}
if (i < 0) {
return false;
}
int j = a.length - 1;
while (a[i] >= a[j]) {
j--;
}
int t = a[i];
a[i] = a[j];
a[j] = t;
Collections.reverse(Arrays.asList(Arrays.copyOfRange(a, i + 1, a.length)));
return true;
}
it will return true until there is a premutation to use it run this code
public static void main(String[] args) {
int[] a = new int[]{0, 1, 2, 3};
do {
System.out.println(Arrays.toString(a));
} while (nextPermutationArray(a));
}
output is
[0, 1, 2, 3]
[0, 1, 3, 2]
[0, 2, 3, 1]
[0, 3, 2, 1]
[1, 3, 2, 0]
[2, 3, 1, 0]
[3, 2, 1, 0]

Sort and rearrange (distinct) arrays

I have two int[] arrays I and J as follows:
int[] I = { 1, 2, 4, 5, 3 };
int[] J = { 8, 7, 6, 3, 2 };
I want to sort I, and then rearrange J using the same indices so the two arrays stay in registration. The result should be:
I = { 1, 2, 3, 4, 5 };
J = { 8, 7, 2, 6, 3 };
I would start by writing a routine to swap elements in an int[]. Something like,
public static void swap(int[] arr, int i, int j) {
if (i == j) {
return;
}
int t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
Then you could use it and Arrays.toString(int[]) and something like
public static void main(String[] args) {
int[] I = { 1, 2, 4, 5, 3 };
int[] J = { 8, 7, 6, 3, 2 };
for (int i = 0; i < I.length - 1; i++) {
for (int j = i + 1; j < I.length; j++) {
if (I[i] > I[j]) {
swap(I, i, j);
swap(J, i, j);
}
}
}
System.out.printf("I = %s%n", Arrays.toString(I));
System.out.printf("J = %s%n", Arrays.toString(J));
}
Output is (as requested)
I = [1, 2, 3, 4, 5]
J = [8, 7, 2, 6, 3]
This can also be accomplished with Java 8 IntStream and additional Pair class representing a 2-tuple (I know, it's a bit ugly because we have to copy the values back to the array):
public class Main {
public static void main(String[] args) {
final int[] I = {1, 2, 4, 5, 3};
final int[] J = {8, 7, 6, 3, 2};
List<Pair> pairs = IntStream.range(0, I.length)
.mapToObj(n -> new Pair(I[n], J[n]))
.sorted((p1, p2) -> p1.i - p2.i)
.collect(Collectors.toList());
for (int k=0; k < pairs.size(); k++) {
Pair p = pairs.get(k);
I[k] = p.i;
J[k] = p.j;
}
System.out.println(Arrays.toString(I));
System.out.println(Arrays.toString(J));
}
public static class Pair {
public int i,j;
public Pair(int i, int j) {
this.i = i;
this.j = j;
}
}
}
Output:
[1, 2, 3, 4, 5]
[8, 7, 2, 6, 3]
Keeping the arrays in sync isn't very pretty, I would strongly suggest to model this properly by using an array of tuple objects instead. Then, it's much simpler:
public class Main {
public static void main(String[] args) {
final Pair[] P = {new Pair(1,8), new Pair(2,7), new Pair(4,6),
new Pair(5,3), new Pair(3,2)};
Arrays.sort(P, (p1, p2) -> p1.i - p2.i);
System.out.println(Arrays.toString(P));
}
public static class Pair {
public int i,j;
public Pair(int i, int j) {
this.i = i;
this.j = j;
}
#Override
public String toString() {
return String.format("(%d, %d)", i, j);
}
}
}
Output:
[(1, 8), (2, 7), (3, 2), (4, 6), (5, 3)]
As #ajb has noted in the comments above, the easiest way to implement this is to use a class modelling a tuple.
This has the advantage that you can use the Arrays.sort builtin which saves you from writing your own sorting algorithm. On the other hand, there is the additional overhead of transferring data from the Tuples to the raw arrays.
However, you may find that in your application you are able to directly use the Tuple objects without transferring them back to arrays.
import java.util.*;
class Tuple implements Comparable<Tuple>
{
int x;
int y;
Tuple(int a, int b)
{
x = a;
y = b;
}
public int compareTo(Tuple another)
{
return Integer.compare(x, another.x);
}
}
class Main
{
public static void main(String args[])
{
int a[] = {1, 2, 4, 5, 3};
int b[] = {8, 7, 6, 3, 2};
Tuple arr[] = new Tuple[a.length];
for (int i=0;i<a.length;i++)
arr[i] = new Tuple(a[i], b[i]);
Arrays.sort(arr);
for (int i=0;i<a.length;i++)
{
a[i] = arr[i].x;
b[i] = arr[i].y;
}
System.out.println(Arrays.toString(a));
System.out.println(Arrays.toString(b));
}
}
And the output:
[1, 2, 3, 4, 5]
[8, 7, 2, 6, 3]

Sorting rows of a 2d integer array from smallest to biggest

I have 2D integer array named arry like this:
[6, 2, 7]
[3, 6, 7]
[5, 6, 1]
[5, 3, 4]
[5, 3, 8]
I want to sort it in the way this would be the result (in order to do so I create new array of the same size, named table):
[3, 6, 7]
[5, 6, 1]
[5, 3, 4]
[5, 3, 8]
[6, 2, 7]
And I have this code:
for (int k = 0; k < numOfArrays; k++) {
int smallest = 2147483647;
int indexSmallest = 0;
for (int h = 0; h < numOfArrays; h++) {
if (arry[h][0] < smallest) {
smallest = arry[h][0];
indexSmallest = h;
}
}
tabel[k] = arry[indexSmallest];
arry[indexSmallest][0] = 2147483647;
}
for (int k = 0; k < numOfArrays; k++) {
System.out.println(Arrays.toString(tabel[k]));
}
The result is:
[2147483647, 6, 7]
[2147483647, 6, 1]
[2147483647, 3, 4]
[2147483647, 3, 8]
[2147483647, 2, 7]
I don't understand how can table contain 2147483647, if I've never set any value of table to 2147483647?
The real problem is this line:
tabel[k] = arry[indexSmallest];
Remember, arrays are objects. This line doesn't copy the inner array, it sets a reference to it.
So at this point both tabel[k] and arry[indexSmallest] point to the same array object. So when you do this:
arry[indexSmallest][0] = 2147483647;
You change it for both arry[indexSmallest] and tabel[k] (since they point to the same object)
To fix the problem, assing to tabel[k] a copy of the array:
tabel[k] = Arrays.copyOf(arry[indexSmallest], 3);
arry[indexSmallest][0] = 2147483647;
This line of code is setting the first element in each row to 2147483647 at the end of your outermost for loop. This is why it appears in each row. I'm not sure what you intended to do here, but this is why you are getting that value.
Remember, Java arrays are objects, which means they are passed by reference. So you're not actually making a copy of the inner arrays; use Arrays.copyOf() for that.
If you're allowed to use Arrays.sort() with a Comparator, you could do it like this.
java.util.Arrays.sort(arry, new java.util.Comparator<int[]>() {
public int compare(int[] a1, int[] a2) {
for (int k = 0; k < a1.length; k++) {
if (a1[k] != a2[k]) {
return a1[k] - a2[k];
}
}
return 0;
}
});
for (int k = 0; k < numOfArrays; k++) {
System.out.println(java.util.Arrays.toString(arry[k]));
}
If that's not allowed, then you can still use the comparison logic inside the above Comparator.compare() method. That's your basic sorting logic regardless of the implementation details.
You have make this info inside of an Object and implement Comparable/Comparator:
public YourObject implements Comparable {
private long a;
private long b;
private long c;
public YourObject (long a, long b, long c){
this.a = a;
this.b = b;
this.c = c;
}
public int compareTo(Object arg0) {
//make your comparison here...
}
}
In main function:
YourObject[] arr = new YourObject[3];
arr[0] = new YourObject (.., .., ..,);
arr[1] = new YourObject (.., .., ..,);
arr[2] = new YourObject (.., .., ..,);
Arrays.sort(arr); //sorting your data
You can greatly simplify your code by using Arrays.sort method, or otherwise you can implement something like this.
Selection sort of a 2d array by column
public static void selectionSort2D(int[][] arr, int column) {
// iterate over all subsets of the rows of the array
// (0-last, 1-last, 2-last, 3-last, ...)
for (int i = 0; i < arr.length; i++) {
// assume the min is the first row element
int min = arr[i][column];
// row index of the min element
int min_i = i;
// check the rows after i to find the smallest
for (int j = i + 1; j < arr.length; j++) {
// if this row element is less,
// then it is the new min
if (arr[j][column] < min) {
min = arr[j][column];
min_i = j;
}
}
// if the min element row is not equal to
// the current one, then swap these rows
if (i != min_i) {
int[] temp = arr[i];
arr[i] = arr[min_i];
arr[min_i] = temp;
}
}
}
// test
public static void main(String[] args) {
int[][] arr = {
{6, 2, 7},
{3, 6, 7},
{5, 6, 1},
{5, 3, 4},
{5, 3, 8}};
// sort by first column
selectionSort2D(arr, 0);
// output
for (int[] row : arr)
System.out.println(Arrays.toString(row));
//[3, 6, 7]
//[5, 6, 1]
//[5, 3, 4]
//[5, 3, 8]
//[6, 2, 7]
}

Finding last five number from input stream

I have input stream of numbers coming like
1 3 5 6 5 6 7 43 54 3 2 ....
At any point of given time how to find the last five number ?
Or you could use a circular buffer:
private class CircularBuffer {
private int[] items;
private int index = 0;
private int size = 0;
public CircularBuffer(int size) {
items = new int[size];
}
public void add(int item) {
items[index] = item;
index = (index + 1) % items.length;
size = Math.min(size + 1, items.length);
}
public int get(int i) {
if (i < 0 || i >= size)
throw new IndexOutOfBoundsException();
return items[(index - size + i + items.length) % items.length];
}
#Override
public String toString() {
StringBuilder builder = new StringBuilder("[");
for (int i = 0; i < size; ++i) {
builder.append(get(i));
builder.append(i < size - 1 ? ", " : "]");
}
return builder.toString();
}
}
Test code:
CircularBuffer b = new CircularBuffer(5);
for (int i = 1; i < 10; ++i) {
b.add(i);
System.out.println(b);
}
Output:
[1]
[1, 2]
[1, 2, 3]
[1, 2, 3, 4]
[1, 2, 3, 4, 5]
[2, 3, 4, 5, 6]
[3, 4, 5, 6, 7]
[4, 5, 6, 7, 8]
[5, 6, 7, 8, 9]
You could save them in a Stack which would be the easiest and 'best' way to do it inmho.
If you (for whatever reason) can't or don't want to use an Stack I would suggest you to implement the "push" method for Arrays:
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int[] numbers = new int[5];
while(true){ // as long as you expect numbers from your stream
push(numbers, sc.nextInt());
}
}
public static void push(int[] arr, int value){
for(int i = 1; i < arr.length; i++){
arr[i - 1] = arr[i];
}
arr[arr.length - 1] = value;
}
Assuming your Stream provides with you with Integers only, via STDIN, one per line - the numbers array now holds the last 5 inputs for you (or 0 as a default value in case less than 5 values arrived so far).
Greetings Tim

Categories

Resources