Appending arrays using method call [duplicate] - java

This question already has answers here:
How can I concatenate two arrays in Java?
(66 answers)
Closed 6 years ago.
I'm a beginner with JAVA so this question is not making much sense:
Write a method called append that accepts two integer arrays as
parameters and returns a new array that contains the result of
appending the second array's values at the end of the first array. For
example, if arrays list1 and list2 store {2, 4, 6} and {1, 2, 3, 4, 5}
respectively, the call of append(list1, list2) should return a new
array containing {2, 4, 6, 1, 2, 3, 4, 5}. If the call instead had
been append(list2, list1), the method would return an array containing
{1, 2, 3, 4, 5, 2, 4, 6}
Help is greatly appreciated. Thanks.

package iran;
public class ExampleTest {
//https://telegram.me/javalike
public int[] append(int[] array1, int[] array2) {
int array[] = new int[array1.length + array2.length];
int counter = 0;
int flage = 0;
for (int i = 0; i < array.length; i++) {
if (i < array1.length) {
array[i] = array1[counter];
counter++;
} else {
if (flage == 0) {
counter = 0;
flage = 1;
}
array[i] = array2[counter];
counter++;
}
}
return array;
}
public static void main(String[] args) {
ExampleTest t = new ExampleTest();
int a[] = { 2, 4, 6 };
int b[] = { 1, 2, 3, 4, 5 };
int c[] = t.append(b, a);
for (int i = 0; i < c.length; i++) {
System.out.print(c[i] + " ");
}
}
}
result:
1 2 3 4 5 2 4 6

Try this.
static int[] append(int[]... a) {
return Stream.of(a)
.flatMapToInt(IntStream::of)
.toArray();
}
and
int[] a = {2, 4, 6};
int[] b = {1, 2, 3, 4, 5};
System.out.println(Arrays.toString(append(a, b)));
result:
[2, 4, 6, 1, 2, 3, 4, 5]
You can also append three or more arrays.

If you are looking for the best performance, you can use native methods like System.arraycopy() instead of a loop.
public static int[] append(int[] a, int[] b)
{
int[] merged = new int[a.length + b.length];
System.arraycopy(a, 0, merged, 0, a.length);
System.arraycopy(b, 0, merged, a.length, b.length);
return merged;
}
But not coming up with your own "manual" solution could defeat the purpose of this assignment.

This works, and is fairly self-explanatory:
int[] append(int[] ary1, int[] ary2) {
int[] arrayOut = new int[ary1.length + ary2.length];
for(int i = 0; i<ary1.length; i++) {
arrayOut[i] = ary1[i];
}
for(int i = ary1.length; i< (ary1.length + ary2.length); i++) {
arrayOut[i] = ary2[i - ary1.length];
}
return arrayOut;
}

Related

How to sort array based on multiples of 3 using Java

I have an array like this one-
{1, 2, 3, 4, 5, 6}
I want to sort it in the order of multiples of 3 with remainders 0, 1 and 2. (the first group is multiples of 3, the second one is multiples of 3 with remainder 1 and the last one is multiples of 3 with remainder 2) and I want to preserve the order in which elements appear in the array.
The result should be -
{3, 6, 1, 4, 2, 5}
I have this code-
int current = 0;
int b = 0;
for (int i = 0; i < 3; i++) { //3 groups
for (int j = current; j < numbers.length; j++) {
if (numbers[j] % 3 == i) { //reminder should be 0,1 or 2
b = numbers[j];
numbers[j] = numbers[current];
numbers[current] = b;
current++;
}
}
}
But this code does not preserve the order in which elements appear in the array. The result I got is-
{3, 6, 1, 4, 5, 2}
But I want the result to be like {3, 6, 1, 4, 2, 5}. How can I achieve this?
Using stream and comparator
int[] array = {1, 2, 3, 4, 5, 6};
List<Integer> lst = Arrays.stream(array)
.boxed()
.sorted(Comparator.comparingInt(o -> o % 3))
.collect(Collectors.toList());
System.out.println(lst);
In your solution you are swapping the elements in place, which shuffles them from the initial order. That's why you don't have the same ordering at the end. I'm not sure if there is another way apart from having a second array to keep the sorted elements, while at the same time iterating over the original one like so:
public static void main(String[] args) {
int[] numbers = new int[]{1, 2, 3, 4, 5, 6};
int[] result = new int[numbers.length];
int b = 0;
int current = 0;
for (int i = 0; i < 3; i++) { //3 groups
for (int j = 0; j < numbers.length; j++) {
if (numbers[j] % 3 == i) { //reminder should be 0,1 or 2
result[current] = numbers[j];
current++;
}
}
}
System.out.println(Arrays.toString(result));
}
Output: [3, 6, 1, 4, 2, 5]
You can use an IntStream and a Comparator to sort the stream:
int[] arr = {1, 2, 3, 4, 5, 6};
int[] arrSorted = IntStream.of(arr).boxed()
.sorted(Comparator.comparingInt(i -> i % 3))
.mapToInt(Integer::intValue)
.toArray();
System.out.println(Arrays.toString(arrSorted));
Output:
[3, 6, 1, 4, 2, 5]
Note: From IntStream.of() javadoc:
Returns a sequential ordered stream whose elements are the specified
values.
I would create a new array of the same size and then place the elements in the correct order. For example like this:
int[] array = {1, 2, 3, 4, 5, 6};
int[] sorted = new int[array.length];
int counter = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < array.length; j++) {
if (array[j] % 3 == i) {
sorted[counter] = array[j];
counter++;
}
}
}
System.out.println(Arrays.toString(sorted));
Output:
[3, 6, 1, 4, 2, 5]
Alternatively, you can use Java 8 features to reduce the amount of code like this:
int[] array = {1, 2, 3, 4, 5, 6};
int[] sorted = Arrays.stream(array).boxed().sorted(Comparator.comparingInt(a -> (a % 3))).mapToInt(i -> i).toArray();
Output:
[3, 6, 1, 4, 2, 5]

how to sort two dimensional array by one column in Java

So what I want is this
int[][] arr=new int[2][8];
input:
1 1 3 1 5 3 7 1
5 2 4 8 3 7 5 2
output:
1 1 5 3 1 7 3 1
2 2 3 4 5 5 7 8
you can see that it is sorted by the second row in ascending order and the first row just follows,
how can I do this? help, please.
I tried doing below
Arrays.sort(arr[1]);
but I don't think it is working. It does sort the second row in ascending order but the first row is not matching the initial pair with the second row
Try this.
public static void main(String[] args) {
int[][] array = {
{1, 1, 3, 1, 5, 3, 7, 1},
{5, 2, 4, 8, 3, 7, 5, 2}
};
List<int[]> list = new AbstractList<int[]>() {
#Override
public int[] get(int index) {
return new int[] {array[1][index], array[0][index]};
}
#Override
public int[] set(int index, int[] value) {
int[] old = get(index);
array[1][index] = value[0];
array[0][index] = value[1];
return old;
}
#Override
public int size() {
return array[0].length;
}
};
Collections.sort(list, Arrays::compare);
for (int[] row : array)
System.out.println(Arrays.toString(row));
}
output:
[1, 1, 5, 3, 1, 7, 3, 1]
[2, 2, 3, 4, 5, 5, 7, 8]
Or
public static void main(String[] args) {
int[][] array = {
{1, 1, 3, 1, 5, 3, 7, 1},
{5, 2, 4, 8, 3, 7, 5, 2}
};
int[] sortedIndexes = IntStream.range(0, array[0].length)
.boxed()
.sorted(Comparator.comparing((Integer i) -> array[1][i])
.thenComparing(i -> array[0][i]))
.mapToInt(Integer::intValue)
.toArray();
int[][] output = IntStream.range(0, array.length)
.mapToObj(r -> IntStream.range(0, array[r].length)
.map(i -> array[r][sortedIndexes[i]])
.toArray())
.toArray(int[][]::new);
for (int[] r : output)
System.out.println(Arrays.toString(r));
}
It may be implemented using helper method(s) to transpose the input array, then transposed array may be sorted by column, and transposed again to restore the original rows/cols:
// create new array to store transposed
public static int[][] transpose(int[][] src) {
return transpose(src, new int[src[0].length][src.length]);
}
// use existing array to store the transposed
public static int[][] transpose(int[][] src, int[][] dst) {
for (int i = 0, n = src.length; i < n; i++) {
for (int j = 0, m = src[i].length; j < m; j++) {
dst[j][i] = src[i][j];
}
}
return dst;
}
Method sortByColumn (reusing the input array):
public static void sortByColumn(int[][] arr, Comparator<int[]> comparator) {
int[][] toSort = transpose(arr);
Arrays.sort(toSort, comparator);
transpose(toSort, arr);
}
Test:
int[][] arr = {
{7, 1, 3, 1, 5, 3, 1, 4, 4},
{5, 2, 4, 8, 3, 7, 5, 2, 5}
};
sortByColumn(arr, Comparator.comparingInt(col -> col[1]));
for (int[] row : arr) {
System.out.println(Arrays.toString(row));
}
Output:
in the first row values appear in the insertion order after sorting by the second element in each column.
[1, 4, 5, 3, 7, 1, 4, 3, 1]
[2, 2, 3, 4, 5, 5, 5, 7, 8]
Square arrays (width == height) may be transposed more efficiently without creating additional array:
public static int[][] transposeSquare(int[][] arr) {
for (int i = 0, n = arr.length; i < n; i++) {
// select the elements only above the main diagonal
for (int j = i + 1, m = arr[i].length; j < m; j++) {
int tmp = arr[i][j];
arr[i][j] = arr[j][i];
arr[j][i] = tmp;
}
}
return arr;
}

Find first duplicate element with lowest second occurrence index

I'm trying to solve a problem on CodeFights called firstDuplicate, that states -
Given an array a that contains only numbers in the range from 1 to
a.length, find the first duplicate number for which the second
occurrence has the minimal index. In other words, if there are more
than 1 duplicated numbers, return the number for which the second
occurrence has a smaller index than the second occurrence of the other
number does. If there are no such elements, return -1.
Example
For a = [2, 3, 3, 1, 5, 2], the output should be firstDuplicate(a) =
3.
There are 2 duplicates: numbers 2 and 3. The second occurrence of 3
has a smaller index than than second occurrence of 2 does, so the
answer is 3.
For a = [2, 4, 3, 5, 1], the output should be firstDuplicate(a) = -1.
My solution -
public class FirstDuplicate {
private static HashMap<Integer, Integer> counts = new HashMap<>();
private static void findSecondIndexFrom(int[] num, int n, int i) {
// given an array, a starting index and a number, find second occurrence of that number beginning from next index
for(int x = i; x < num.length; x++) {
if(num[x] == n) {
// second occurrence found - place in map and terminate
counts.put(n, x);
return;
}
}
}
private static int firstDuplicate(int[] a) {
// for each element in loop, if it's not already in hashmap
// find it's second occurrence in array and place number and index in map
for(int i = 0; i < a.length; i++) {
if(!counts.containsKey(a[i])) {
findSecondIndexFrom(a, a[i], i+1);
}
}
System.out.println(counts);
// if map is empty - no duplicate elements, return -1
if(counts.size() == 0) {
return -1;
}
// else - get array of values from map, sort it, find lowest value and return corresponding key
ArrayList<Integer> values = new ArrayList<>(counts.values());
Collections.sort(values);
int lowest = values.get(0);
//System.out.println(lowest);
for(Map.Entry<Integer, Integer> entries: counts.entrySet()) {
if(entries.getValue() == lowest) {
return entries.getKey();
}
}
return -1;
}
public static void main(String[] args) {
// int[] a = new int[]{2, 3, 3, 1, 5, 2};
//int[] a = new int[]{2, 4, 3, 5, 1};
//int[] a = new int[]{8, 4, 6, 2, 6, 4, 7, 9, 5, 8};
//int[] a = new int[]{1, 1, 2, 2, 1};
int[] a = new int[]{10, 6, 8, 4, 9, 1, 7, 2, 5, 3};
System.out.println(firstDuplicate(a));
}
}
This solution passes only for about 4 of the 11 test cases on CodeFights. However, I manually executed each one of the test cases in my IDE, and each one produces the right result.
I can't figure out why this won't work in CodeFights. Does it have something to do with the use of the static HashMap?
Edited: Since adding and checking if element is present in Set can be done in one step, code can be simplified to:
public static int findDuplicateWithLowestIndex(int... a){
Set<Integer> set = new HashSet<>();
for(int num : a){
if(!set.add(num)){
return num;
}
}
return -1;
}
You're completly right Patrick.
Use this solution: here duplicateIndex should be very large number.
package sample;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Duplicate {
public static Integer secondIndex(Integer[] arr) {
List<Integer> arrlist = new ArrayList<>(Arrays.asList(arr));
int duplicateIndex = 999;
int ele = 0;
for (int i = 0; i < arrlist.size(); i++) {
int secondIndex = getSecondIndex(arrlist, arrlist.get(i));
if (secondIndex >= 0 && duplicateIndex > secondIndex) {
duplicateIndex = secondIndex;
ele = arrlist.get(i);
}
}
return duplicateIndex == 999 ? -1 : ele;
}
public static int getSecondIndex(List<Integer> arr, int ele) {
List<Integer> var0 = new ArrayList<>(arr);
var0.set(var0.indexOf(ele), -1);
return var0.indexOf(ele);
}
public static void main(String[] str) {
// Integer[] arr = new Integer[] { 2, 3, 3, 1, 5, 2 };
// Integer[] arr = new Integer[] { 2, 4, 3, 5, 1 };
// Integer[] arr = new Integer[] { 8, 4, 6, 2, 6, 4, 7, 9, 5, 8 };
// Integer[] arr = new Integer[]{1, 1, 2, 2, 1};
Integer[] arr = new Integer[] { 10, 6, 8, 4, 9, 1, 7, 2, 5, 3 };
System.out.println(secondIndex(arr));
}
}
Solution in Javascript
function solution(a) {
const duplicates = [];
for (const i of a) {
if (duplicates.includes(i))
return i;
else
duplicates.push(i);
}
return -1;
}
console.log(solution([2, 1, 3, 5, 3, 2])); // 3
console.log(solution([2, 2])); // 2
console.log(solution([2, 4, 3, 5, 1])); // -1

Concatenating two arrays with alternating values

What is the best way to concatenate two arrays with alternating values?
Let's say array1 is:
[1, 3, 5, 7]
array2 is:
[2, 4, 6, 8]
I want to combine these two arrays, so that the result is:
[1, 2, 3, 4, 5, 6, 7, 8]
In Java:
int[] a1 = { 1, 3, 5, 7 };
int[] a2 = { 2, 4, 6, 8 };
int[] concat = new int[a1.length * 2];
for (int i = 0; i < concat.length; i++) {
// concatenation
}
System.out.println(concat.toString());
// should be [1, 2, 3, 4, 5, 6, 7, 8]
Update: No sorting is required, as the arrays are already sorted, using Arrays.sort(array)
A basic way
int[] concat = new int[a1.length * 2];
int index = 0;
for (int i = 0; i < a1.length; i++) {
concat[index++] = a1[i];
concat[index++] = a2[i];
}
assuming that both array will be of same size.
Put the elements of both array in a list and then sort it.You can use lambdas also
Integer[] a1 = { 1, 3, 5, 7 };
Integer[] a2 = { 2, 4, 6, 8 };
List<Integer> list = new ArrayList<>();
list.addAll(Arrays.asList(a1));
list.addAll(Arrays.asList(a2));
System.out.println("Before Sorting "+list);
Collections.sort(list,(a, b) -> Integer.compare(a,b));
System.out.println("After Sorting "+list);
Output
Before Sorting [1, 3, 5, 7, 2, 4, 6, 8]
After Sorting [1, 2, 3, 4, 5, 6, 7, 8]
If you want to zip together any length arrays (where then lengths differ, the remaining is appended to the result):
public static int[] zip(int[] a, int[] b){
int[] result = new int[a.length + b.length];
int index = 0;
final int minLen = Math.min(a.length, b.length);
for (int i = 0; i < minLen; i++) {
result[index++] = a[i];
result[index++] = b[i];
}
if(a.length > minLen)
System.arraycopy(a, minLen, result, index, a.length - minLen);
else if(b.length > minLen)
System.arraycopy(b, minLen, result, index, b.length - minLen);
return result;
}
Try it like this:
int[] concat = new int[a1.length + a2.length];
int k = 0, m = 0;
for (int i = 0; i < concat.length; i++) {
if( k < al.length && a1[k] <= a2[m])
concat[i] = a1[k++];
else
concat[i] = a2[m++];
}
NB: The result will be sorted as in your desired output.
you could also use two variables in your loop like this
int[] a1 = { 1, 3, 5, 7 };
int[] a2 = { 2, 4, 6, 8 };
int[] concat = new int[a1.length + a2.length];
for (int i = 0, j = 0; i+j < concat.length;) {
if(i<a1.length) {
concat[i+j] = a1[i++];
}
if(j<a2.length) {
concat[i+j] = a2[j++];
}
}
System.out.println(Arrays.toString(concat));
Try This if it solves ur problem
int[] a1 = { 1, 3, 5, 7 };
int[] a2 = { 2, 4, 6, 8 };
int[] concat = new int[a1.length + a2.length];
System.arraycopy(a1, 0, concat, 0, a1.length);
System.arraycopy(a2, 0, concat, a1.length, a2.length);
Arrays.sort(concat);
System.out.println(Arrays.toString(concat));
Output:
[1, 2, 3, 4, 5, 6, 7, 8]
There are utility methods for example addALL() method from ArrayUtil class. But what they do is simple concatenate. For your problem you need to write your own logic. For example the following code ensures correct alternate concatenation even if arrays are of unequal length.
int[] a1 = { 1, 3, 5, 7 };
int[] a2 = { 2, 4, 6, 8, 9, 10, 122 };
int totalLen = a1.length + a2.length;
int[] concat = new int[totalLen];// I made a change here incase the
// arrays are not of equal length
int i = 0; // this will be the concat array index counter
int j1 = 0; // this will be the a1 array index counter
int j2 = 0; // this will be the a2 array index counter
while (i < totalLen) {
if ((j1 < a1.length)) {
concat[i] = a1[j1];
i++;
j1++;
}
if ((j2 < a2.length)) {
concat[i] = a2[j2];
i++;
j2++;
}
}

Java - Return an array from array with two given indexes

Let's say I have an array:
int[] values = {1, 2, 3, 4, 5, 6, 7 , 8, 9, 0};
With two indexes (let's say 2 and 5), I want to be able to return array from indexes 2 to 5 from the variable values given above. The final output should be this:
newValues[] = {3, 4, 5, 6};
Also, how would this procedure be used with multi dimensional arrays?
I would have googled this, but I'm not sure what to google, so I came here.
Use java.util Arrays class. Use copyOfRange(int[] original, int from, int to) method:
newValues[] = Arrays.copyOfRange(values, 2, 6);
Try the following
public static void main(String[] args)
{
int[] values = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
int start = 2, end = 5; // Index
int[] newValues = new int[end - start + 1]; // Create new array
for (int i = start; i <= end; i++) {
newValues[i - start] = values[i]; // Assign values
}
// Print newValues
for (int v : newValues) {
System.out.print(v + " ");
}
}
Output:
3 4 5 6
Try the following for 2D arrays:
public int[][] getRange(int[][] src, int x, int y, int x2, int y2) {
int[][] ret = new int[x2-x+1][y2-y+1];
for(int i = 0; i <= x2-x; i++)
for(int j = 0; j <= y2-y; j++)
ret[i][j] = src[x+i][y+j];
return ret;
}
For 1D Arrays, Arrays.copyOfRange() should be fine and for more dimensions you can simply add more params and for loops
You can use the following :
int[] values = {1, 2, 3, 4, 5, 6, 7 , 8, 9, 0};
int newValues[] = new int[4];
System.arraycopy(values,1,newValues,0,4)
Here's the complete code :
public class CopyRange {
public static void main (String...args){
int[] values = {1, 2, 3, 4, 5, 6, 7 , 8, 9, 0};
int newValues[] = new int[4];
System.arraycopy(values,1,newValues,0,4);
for (int i =0;i <newValues.length;i++)
System.out.print(newValues[i] + " ");
}
}
The System class has an arraycopy method that you can use to efficiently copy data from one array into another:
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)

Categories