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]
Related
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]
[]
I've been going through this MOOC.fi Java course and got to the problem about developing a selection sort algorithm on this page (https://java-programming.mooc.fi/part-7/2-algorithms). I don't have the solutions, so I was wondering if anyone here could help me solve this problem. Basically, I got through all the steps uptil Part 4, but when I tried to make the selection sort method, my method only sorted the numbers correctly until it got to the second to last number, and then it started switching the numbers incorrectly. Can anyone look over my code and tell me where I went wrong?
import java.util.Arrays;
public class MainProgram {
public static void main(String[] args) {
// Testing methods
// Test Part 1
int[] numbers = {6, 5, 8, 7, 11};
System.out.println("Smallest: " + MainProgram.smallest(numbers));
// Testing Part 2
System.out.println("Index of the smallest number: " + MainProgram.indexOfSmallest(numbers));
// Testing Part 3
System.out.println(MainProgram.indexOfSmallestFrom(numbers, 0));
System.out.println(MainProgram.indexOfSmallestFrom(numbers, 1));
System.out.println(MainProgram.indexOfSmallestFrom(numbers, 2));
// Testing Part 4
int[] numbers2 = {3, 2, 5, 4, 8};
System.out.println(Arrays.toString(numbers2));
MainProgram.swap(numbers2, 1, 0);
System.out.println(Arrays.toString(numbers2));
MainProgram.swap(numbers2, 0, 3);
System.out.println(Arrays.toString(numbers2));
// Testing Part 5
int[] numbers3 = {8, 3, 7, 9, 1, 2, 4};
MainProgram.sort(numbers3);
}
// Part 1
public static int smallest(int[] array) {
int smallest = array[0];
for (int i = 0; i < array.length; i++) {
if (array[i] < smallest) {
smallest = array[i];
}
}
return smallest;
}
// Part 2
public static int indexOfSmallest(int[] array){
int smallest = array[0];
int i;
int finalIndex = 0;
for (i = 0; i < array.length; i++) {
if (array[i] < smallest) {
smallest = array[i];
finalIndex = i;
}
}
return finalIndex;
}
// Part 3
public static int indexOfSmallestFrom(int[] table, int startIndex) {
int smallest = table[startIndex];
int i = startIndex;
int finalIndex = 0;
for (i = startIndex; i < table.length; i++) {
if (table[i] < smallest) {
smallest = table[i];
finalIndex = i;
}
}
return finalIndex;
}
// Part 4
public static void swap(int[] array, int index1, int index2) {
int temp = array[index1];
array[index1] = array[index2];
array[index2] = temp;
}
// Part 5
public static void sort(int[] array) {
int smallestIndex;
for (int i = 0; i < array.length; i++) {
smallestIndex = indexOfSmallestFrom(array, i);
swap(array, smallestIndex, i);
System.out.println(Arrays.toString(array));
}
}
}
Here is the wrong output:
[1, 3, 7, 9, 8, 2, 4]
[1, 2, 7, 9, 8, 3, 4]
[1, 2, 3, 9, 8, 7, 4]
[1, 2, 3, 4, 8, 7, 9]
[1, 2, 3, 4, 7, 8, 9]
[8, 2, 3, 4, 7, 1, 9]
[9, 2, 3, 4, 7, 1, 8]
In the 3 block you set the
finalIndex = 0;
It should be set to the startIndex
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]
let's say I have two array;
Integer[] array= { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 200, 5, 6, 5 };
Integer[] array2= { 12, 2 ,3, 2, 200, 5 };
Im trying to make a method that return an array with all the element removed except those who are in also present in array2, so the output of this method should be
{2 ,3, 5, 200, 5, 5 }
I dont want to use another data structure and i have no idea how to code what im trying to do, im not sure how i can determinate the resulting array length
thanks
Here is a solution which uses only arrays and no other data structure at all. The retainAll method will return an array with some nulls in it. You can make some code to use that array and create an array with no nulls. Its really easy.
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
Integer[] array = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 200, 5, 6, 5 };
Integer[] array2 = { 12, 2, 3, 2, 200, 5 };
Integer[] res = retainAll(array, array2);
String str = Arrays.toString(res);
System.out.println(str);
res = removeArrayDuplicates(res);
str = Arrays.toString(res);
System.out.println(str);
}
public static Integer[] retainAll(Integer[] a, Integer[] b) {
int ln1 = a.length;
int ln2 = b.length;
Integer[] res = new Integer[(ln1 < ln2) ? ln1 : ln2];
Integer[] small = (ln1 < ln2) ? a : b;
Integer[] big = (ln1 < ln2) ? b : a;
boolean found = false;
for (int i = 0; i < small.length; i++) {
found = arrayContains(big, small[i]);
if (found == true) {
res[i] = small[i];
}
}
return res;
}
public static Integer[] removeArrayDuplicates(Integer[] a) {
int len = a.length;
int dups = 0;
boolean noNulls = false;
for (int i = 0; i < len; i++) {
for (int j = i + 1; j < len; j++) {
noNulls = a[i] != null && a[j] != null;
if (noNulls && a[i].equals(a[j])) {
a[j] = null;
dups++;
}
}
}
return a;
}
public static boolean arrayContains(Object[] a, Integer b) {
boolean contains = false;
for (Object c : a) {
if (c != null && c.equals(b)) {
contains = true;
break;
}
}
return contains;
}
}
If I understand your question, you could begin by creating a contains(Integer[], Integer) method. Iterate the array and return true if the array contains the value.
private static boolean contains(Integer[] a, Integer v) {
for (Integer t : a) {
if (t.equals(v)) {
return true;
}
}
return false;
}
Then you can leverage that to iterate your arrays twice. Once to perform a count, and the second time to populate a newly created array with the count number of elements. Something like,
public static Integer[] retainAll(Integer[] a, Integer[] b) {
int count = 0;
for (Integer val : a) {
if (contains(b, val)) {
count++;
}
}
Integer[] out = new Integer[count];
count = 0;
for (Integer val : a) {
if (contains(b, val)) {
out[count++] = val;
}
}
return out;
}
Then to test it,
public static void main(String[] args) {
Integer[] array = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 200, 5, 6, 5 };
Integer[] array2 = { 12, 2, 3, 2, 200, 5 };
System.out.println(Arrays.toString(retainAll(array, array2)));
}
Output is the requested
[2, 3, 5, 200, 5, 5]
Of course, you could also use Arrays.asList(T...) and retainAll() like
public static Integer[] retainAll(Integer[] a, Integer[] b) {
List<Integer> al = new ArrayList<>(Arrays.asList(a));
al.retainAll(Arrays.asList(b));
return al.toArray(new Integer[al.size()]);
}
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.