Related
I have managed to create both arrays, however I can't figure out how to combine the two arrays. Every tutorial I see merges them as such:
int[] arr1 = {3, 3, 5, 6, 8, 9};
int[] arr2 = {3, 4, 5, 6};
// Output: 3, 4, 5, 6, 8, 9
What I need is something that would output: 3, 3, 3, 4, 5, 5, 6, 6, 8, 9
Here is the code I have written so far:
import java.util.Scanner;
public class Merger {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int[] arr1 = new int[10000];
int[] arr2 = new int[10000];
int[] merged = new int[20000];
int a1 = 0;
int a2 = 0;
int size = -1;
int size2 = -1;
int sizecheck = 0;
int size2check = 0;
System.out
.println("Enter the values for the first array, up to 10,000 values, enter a negative number to quit");
for (int i = 0; i < arr1.length; i++) {
arr1[i] = scan.nextInt();
merged[i] = arr1[i];
if (arr1[i] <= 0) {
break;
}
if (size <= arr1[i]) {
size = arr1[i];
sizecheck++;
}
a1++;
}
System.out
.println("Enter the values for the second array, up to 10,000 values, enter a negative number to quit");
for (int i = 0; i < arr2.length; i++) {
arr2[i] = scan.nextInt();
merged[i + a1] = arr2[i];
if (arr2[i] <= 0) {
break;
}
if (size2 <= arr2[i]) {
size2 = arr2[i];
size2check++;
}
a2++;
}
System.out.println("First Array: ");
for (int i = 0; i < a1; i++) {
System.out.print(" " + arr1[i]);
}
System.out.println("\nSecond Array: ");
for (int i = 0; i < a2; i++) {
System.out.print(" " + arr2[i]);
}
}
}
This prints both arrays out, however does not combine and sort the two.
Here's the code ! There may be a faster/easier way to do it but this one works as long as the 2 arrays are sorted
public static void main(String[] args) {
int[] a1 = {1, 2, 3, 5};
int[] a2 = {1, 3, 4, 4, 4, 5};
int[] a3 = merge(a1, a2);
for (int i : a3) {
System.out.print(i);
}
}
public static int[] merge(int[] a1, int[] a2) {
int[] a3 = new int[a1.length + a2.length];
int indexA1 = 0;
int indexA2 = 0;
for (int i = 0; i < a3.length; i++) {
int n;
if (indexA1 == a1.length && indexA2 < a2.length) {
n = a2[indexA2];
indexA2++;
} else if (indexA1 < a1.length && indexA2 == a2.length) {
n = a1[indexA1];
indexA1++;
} else {
if (a1[indexA1] < a2[indexA2]) {
n = a1[indexA1];
indexA1++;
} else {
n = a2[indexA2];
indexA2++;
}
}
a3[i] = n;
}
return a3;
}
I assume that you are not yet familiar with Streams, but I would like to give you an example of what you can do with them.
Add import
import java.util.stream.IntStream;
Add this at the end of your main method
System.out.println("");
IntStream arr1Stream = IntStream.of(arr1).limit(a1); //creates an InStream with the first a1 values of arr1
IntStream arr2Stream = IntStream.of(arr2).limit(a2);
int[] both = IntStream.concat(arr1Stream, arr2Stream).sorted().toArray(); //combines the two streams, sorts them an converts them to an Array
System.out.println(Arrays.toString(both)); //easy way to print an array
The easiest way is to use a Stream.
int[] arr1 = {3, 3, 5, 6, 8, 9};
int[] arr2 = {3, 4, 5, 6};
Stream both arrays.
flatMap them to a single IntStream
sort them
convert to an array
int [] combined = Stream.of(arr1,arr2)
.flatMapToInt(Arrays::stream)
.sorted()
.toArray();
System.out.println(Arrays.toString(combined));
Prints
[3, 3, 3, 4, 5, 5, 6, 6, 8, 9]
A non-stream approach can be done as follows:
// increase arr1 to make room for arr2
int oldLen = arr1.length;
arr1 = Arrays.copyOf(arr1, arr1.length+arr2.length);
// copy arr2 starting at 0, to arr1 starting at the old length
// positon of arr1 for a length of arr2
System.arraycopy(arr2, 0, arr1, oldLen, arr2.length);
// sort and print
Arrays.sort(arr1);
System.out.println(Arrays.toString(arr1));
Prints
[3, 3, 3, 4, 5, 5, 6, 6, 8, 9]
Although your question, as asked, said nothing about merging sorted arrays, here is how you would do it.
The algorithm is simple. Just iterate thru each array and compare current values.
if arr1[i] <= arr2[k], copy arr1[i] to result, advance i by 1
else copy arr2[k] to result, advance k by 1.
in all cases the index to result, r, is advanced by 1
public int[] merge(int[] arr1, int[] arr2) {
// result array
int[] result = new int[arr1.length + arr2.length];
int r = 0;
int k = 0;
int i = 0;
// Iterate thru the arrays, copying the lowest or equal value
// to the target array. This process will cease when one of the arrays
// has been fully processed.
for (; i < arr1.length && k < arr2.length; ) {
for (; k < arr2.length && i < arr1.length;) {
if (arr1[i] <= arr2[k]) {
result[r++] = arr1[i++];
}else {
result[r++] = arr2[k++];
}
}
}
Having reached this far in the algorithm, one of the arrays must have been completely processed. So try and copy both. For the empty array, the while loop basically acts like an if statement.
while (i < arr1.length) {
result[r++] = arr1[i++];
}
while (k < arr2.length) {
result[r++] = arr2[k++];
}
// return the result
return result;
}
public class Merger {
public static void main(String[] args) {
int[] arr1 = { 3, 3, 5, 6, 8, 9 };
int[] arr2 = { 3, 4, 5, 6 };
int[] res = merge(arr1, arr2);
System.out.println(Arrays.toString(res));
}
public static int[] merge(int[] arr1, int[] arr2) {
int[] res = new int[arr1.length + arr2.length];
for (int i = 0, a1 = 0, a2 = 0; i < res.length; i++) {
if (a1 == arr1.length)
res[i] = arr2[a2++];
else if (a2 == arr2.length)
res[i] = arr1[a1++];
else
res[i] = arr1[a1] <= arr2[a2] ? arr1[a1++] : arr2[a2++];
}
return res;
}
}
A simple solution can be written using the classes, Arrays and System.
Steps:
Copy elements of arr1[] into a new array (say, output[]) whose size is the sum of the sizes of the given arrays.
Copy the elements of arr2[], after the element of arr1[], into output[]
Sort output[]
Demo:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] arr1 = { 3, 3, 5, 6, 8, 9 };
int[] arr2 = { 3, 4, 5, 6 };
// Copy elements of arr1[] into a new array whose size is the sum of the sizes
// of the given arrays
int[] output = Arrays.copyOf(arr1, arr1.length + arr2.length);
// Copy the elements of arr2[], after the element of arr1[], into output[]
System.arraycopy(arr2.clone(), 0, output, arr1.length, arr2.length);
// Sort output[]
Arrays.sort(output);
// Display output[]
System.out.println(Arrays.toString(output));
}
}
Output:
[3, 3, 3, 4, 5, 5, 6, 6, 8, 9]
You can use System.arraycopy method for this purpose:
int[] arr1 = {3, 3, 5, 6, 8, 9};
int[] arr2 = {3, 4, 5, 6};
// create a new array of total length
int[] arr3 = new int[arr1.length + arr2.length];
// copy first array to the beginning of the total array
System.arraycopy(arr1, 0, arr3, 0, arr1.length);
// copy second array to the end of the total array
System.arraycopy(arr2, 0, arr3, arr1.length, arr2.length);
// sort the total array
Arrays.sort(arr3);
System.out.println(Arrays.toString(arr3));
// [3, 3, 3, 4, 5, 5, 6, 6, 8, 9]
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 4 years ago.
Improve this question
Task is to find the first element of an array that is not consecutive.
E.g. If we have an array [1,2,3,4,6,7,8] then 1 then 2 then 3 then 4 are all consecutive but 6 is not, so that's the first non consecutive number.
If the whole array is consecutive then return null
Here is my solution:
import java.util.ArrayList;
import java.util.List;
class FirstNonConsecutive {
private static int[] arr = new int[]{1, 2, 3, 4, 5, 6, 7, 8};
private static List<Integer> list = new ArrayList<Integer>();
private static Integer[] arrtwovalues = new Integer[arr.length];
private static Integer solve;
static Integer find(final int[] array) {
int[] temp = new int[array.length];
int possition = array[0];
for (int i = 0; i < array.length - 1; i++) {
temp[i] = array[i + 1];
}
for (int i = 0; i < temp.length; i++) {
if (temp[i] == 0) {
temp[i] = possition;
}
}
for (int i = 0; i < array.length; i++) {
if (temp[i] - array[i] == 2) {
arrtwovalues[i] = temp[i];
}
}
for (int i = 0; i < array.length; i++) {
if (temp[i] - array[i] == 2) {
arrtwovalues[i] = temp[i];
}
}
int counter = 0;
for (int i = 0; i < arrtwovalues.length; i++) {
if (arrtwovalues[i] != null) {
counter++;
}
}
for (int i = 0; i < arrtwovalues.length; i++) {
if (arrtwovalues[i] != null) {
list.add(arrtwovalues[i]);
}
}
for (int i = 0; i < list.size(); i++) {
if (list.size() > 0) {
solve = list.get(0);
}
}
System.out.println(solve);
if (list.size() > 0) {
return solve;
}
else return null;
}
public static void main(String[] args) {
find(arr);
}
}
This is my tests:
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public final class FirstNonConsecutiveTest {
#Test public void basicTests() {
assertEquals(Integer.valueOf(6), FirstNonConsecutive.find(new int[]{1, 2, 3, 4, 6, 7, 8}));
assertEquals(null, FirstNonConsecutive.find(new int[]{1, 2, 3, 4, 5, 6, 7, 8}));
assertEquals(Integer.valueOf(6), FirstNonConsecutive.find(new int[]{4, 6, 7, 8, 9, 11}));
assertEquals(Integer.valueOf(11), FirstNonConsecutive.find(new int[]{4, 5, 6, 7, 8, 9, 11}));
assertEquals(null, FirstNonConsecutive.find(new int[]{31, 32}));
assertEquals(Integer.valueOf(0), FirstNonConsecutive.find(new int[]{-3, -2, 0, 1}));
assertEquals(Integer.valueOf(-1), FirstNonConsecutive.find(new int[]{-5, -4, -3, -1}));
}
}
This test does not pass:
assertEquals(null, FirstNonConsecutive.find(new int[]{1, 2, 3, 4, 5, 6, 7, 8}));
java.lang.AssertionError:
Expected :null
Actual :6
<Click to see difference>
Process finished with exit code -1
As it says: Expected :null and Actual :6
But if I try that test-case with my main method then it returns 6 correctly and everything seems to work correctly.
Why does my test not pass? What did I miss?
Your code is way to much complicated for this task. Try something simpler to avoid mistakes, like this :
find(int[] arr) {
if(arr.length > 0) {
for(int i=1; i<arr.length; i++) {
if(arr[i]-1 != arr[i-1]){
System.out.println("The element " + arr[i] + " at the index " + i + " is the first not consecutive element of the array";
return arr[i];
}
}
}
return null; //If we reach the end of the loop, there is no number not consecutive to a previous one.
}
Currently your problem is that arrtwovalues and solve are static. So when you run your first test, you enter some values inside them. And when you run your second test, they still contain these values so it returns previous value : 6.
When you manually test your code, it return null because you did not make the first test before, so arrtwovalues and solve are not already containing values.
Because of this:
private static int[] arr = new int[]{1, 2, 3, 4, 5, 6, 7, 8};
private static List<Integer> list = new ArrayList<Integer>();
private static Integer[] arrtwovalues = new Integer[arr.length];
First of all, the variable arrtwovalues depends on the size of arr.length, which is always the same. Additionally, these values are not reset between the test runs as all of your testing code is inside the same method.
Put these variables as local variables inside your method instead and use the array.length instead:
static Integer find(final int[] array) {
List<Integer> list = new ArrayList<Integer>();
Integer[] arrtwovalues = new Integer[array.length];
int[] temp = new int[array.length];
...
This will solve that test-case, but you have one more failing test-case:
assertEquals(Integer.valueOf(0), FirstNonConsecutive.find(new int[]{-3, -2, 0, 1}));
Which seems to be caused by your code handling 0 as a special case and returning null in that case.
It would be better to put each test-case in its own method annotated by #Test, like this:
#Test
public void basicTests1() {
assertEquals(Integer.valueOf(6), FirstNonConsecutive.find(new int[]{1, 2, 3, 4, 6, 7, 8}));
}
#Test
public void basicTests2() {
assertEquals(null, FirstNonConsecutive.find(new int[]{1, 2, 3, 4, 5, 6, 7, 8}));
}
#Test
public void basicTests3() {
assertEquals(Integer.valueOf(6), FirstNonConsecutive.find(new int[]{4, 6, 7, 8, 9, 11}));
}
#Test
public void basicTests4() {
assertEquals(Integer.valueOf(11), FirstNonConsecutive.find(new int[]{4, 5, 6, 7, 8, 9, 11}));
}
#Test
public void basicTests5() {
assertEquals(null, FirstNonConsecutive.find(new int[]{31, 32}));
}
#Test
public void basicTests6() {
assertEquals(Integer.valueOf(0), FirstNonConsecutive.find(new int[]{-3, -2, 0, 1}));
}
#Test
public void basicTests7() {
assertEquals(Integer.valueOf(-1), FirstNonConsecutive.find(new int[]{-5, -4, -3, -1}));
}
You code looks complicated for this simple problem. This would do the job
public Integer findFirstNonConsecutiveNumber(int[] arr){
int element=-1;
boolean found=false;
;
for(int i=1;i < arr.length;i++){
int prev=arr[i-1];
if(arr[i]!=prev + 1)
{
element=arr[i];
found=true;
break;
}
}
if(found)
return element;
else
return null;
}
replace all field in to the method itself, and past all test.
import java.util.ArrayList;
import java.util.List;
class FirstNonConsecutive {
static Integer find(final int[] array) {
List<Integer> list = new ArrayList<Integer>();
Integer[] arrtwovalues = new Integer[array.length];
Integer solve = null;
int[] newtemp = new int[array.length];
for (int i = 0; i < array.length - 1; i++) {
newtemp[i] = array[i + 1];
}
for (int i = 0; i < array.length; i++) {
if (newtemp[i] - array[i] == 2) {
arrtwovalues[i] = newtemp[i];
}
}
for (int i = 0; i < arrtwovalues.length; i++) {
if (arrtwovalues[i] != null) {
list.add(arrtwovalues[i]);
}
}
for (int i = 0; i < list.size(); i++) {
if (list.size() > 0) {
solve = list.get(0);
}else solve = null;
}
return solve;
}
public static void main(String[] args) {
int[] arr = new int[]{4, 6, 7, 8, 9, 11};
System.out.println(find(arr));
}
}
Give it a try with the following find() method:
public Integer find(final int[] array) {
Integer val = null; // 1
for (int i = 0; i < array.length - 1; i++) { // 2
int current = array[i]; // 3
int next = array[i + 1]; // 4
if (current + 1 != next) { // 5
val = next; // 6
break; // 7
}
}
return val; // 8
}
1 - Initializing the Integer variable "val" as null.
2 - i = 0 means that the loop will start from the first element of the input "array". "i < array.length - 1" means that the loop will continue till the second last element of the array or in other words the loop will exclude the last element.
3 - Current element of the array
4 - Next element of the array
5 - Consecutive means (current + 1 = next). This if condition is checking for the not-consecutive element.
6 - If the not consecutive element is found then it is stored into the "val" variable.
7 - Since the not consecutive element is found it is not required to check the rest of the elements.
8 - If the not consecutive element is found (6) then that element will be returned, otherwise null (1) will be returned.
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 need to efficiently sort through 4 arrays and return 2 results.
The first result will contain all numbers that exist in the arrays.
The second result will contain, all occurrences of each number in the result
int[] a = [1,2,3,4,5];
int[] b = [1,2,3,4,5,6];
int[] c = [1,3,7];
int[] d = [2,3,4,8,9,10];
int[] result1 = [1,2,3,4,5,6,7,8,9,10];
int[] result2 = [1,1,1,2,2,2,3,3,3,3,4,4,4,5,5,6,7,8,9,10];
Step 1: Combine all the arrays
Step 2: Sort arrays using Arrays.sort(array);
Step 3: Remove the duplicates.
int[] a = {1,2,3,4,5};
int[] b = {1,2,3,4,5,6};
int[] c = {1,3,7};
int[] d = {2,3,4,8,9,10};
int[] resultArray1 = new int[a.length+b.length+c.length+d.length];
int arrayIndex = 0;
for (int i=0; i< a.length ; i++, arrayIndex++ )
{
resultArray1[arrayIndex] = a[i];
}
for (int i=0; i< b.length ; i++, arrayIndex++ )
{
resultArray1[arrayIndex] = b[i];
}
for (int i=0; i< c.length ; i++, arrayIndex++ )
{
resultArray1[arrayIndex] = c[i];
}
for (int i=0; i< d.length ; i++, arrayIndex++ )
{
resultArray1[arrayIndex] = d[i];
}
// Sorting Arrays
System.out.println("Array before Sort"+Arrays.toString(resultArray1));
Arrays.sort(resultArray1);
System.out.println("Array after Sort"+Arrays.toString(resultArray1));
// Removing duplicates
Set<String> set = new HashSet<String>();
for (int i = 0; i < resultArray1.length; i++) {
set.add(""+resultArray1[i]); // To convert to string
}
String[] uniqueStringArray = set.toArray(new String[set.size()]); ;
int [] uniqueIntArray = new int [uniqueStringArray.length];
// Converting string array to int array
for(int i=0;i<uniqueStringArray.length;i++)
{
uniqueIntArray[i]= Integer.parseInt(uniqueStringArray[i]);
}
Arrays.sort(uniqueIntArray);
System.out.println("Unique Array after Sort"+Arrays.toString(uniqueIntArray));
Output:
Array before Sort[1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 6, 1, 3, 7, 2, 3, 4, 8, 9, 10]
Array after Sort[1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 6, 7, 8, 9, 10]
Unique Array after Sort[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Combine all 4 arrays in 1 array
sort Array
Remove Dublicate from array
import java.util.Vector;
class sort
{
public static void main(String args[])
{
int[] a = {1,2,3,4,5};
int[] b = {1,2,3,4,5,6};
int[] c = {1,3,7};
int[] d = {2,3,4,8,9,10};
int[] s = combine(a,b,c,d); //concate array using concate function
int[] sort = sort(s);//sort array using sort function
//SORTING ARRAY
System.out.print("ARRAY AFTER SORT ");
System.out.print("[");
for(int i=0;i<sort.length;i++)
{
if(i==sort.length-1)
System.out.print(sort[i]);
else
System.out.print(sort[i]+",");
}
System.out.println("]\n");
//REMOVE DUPLICATE
int[] removedups=removedups(sort);// Remove Duplicate item from array using removedups
System.out.print("ARRAY REMOVE DUPLICATE ");
System.out.print("[");
for(int i=0;i<removedups.length;i++)
{
if(i==removedups.length-1)
System.out.print(removedups[i]);
else
System.out.print(removedups[i]+",");
}
System.out.print("]");
}
public static int[] combine(int a[],int b[],int c[],int d[])//combine array
{
int sort []=new int[a.length+b.length+c.length+d.length];
int j=0;
for(int i=0;i<a.length;i++)
{
sort[j]=a[i];
j++;
}
for(int i=0;i<b.length;i++)
{
sort[j]=b[i];
j++;
}
for(int i=0;i<c.length;i++)
{
sort[j]=c[i];
j++;
}
for(int i=0;i<d.length;i++)
{
sort[j]=d[i];
j++;
}
return sort;
}
public static int[] sort(int s[]) // sort array
{
int temp;
for(int i=0;i<s.length;i++)
{
for(int j=i+1;j<s.length-1;j++)
{
if(s[i]>s[j])
{
temp=s[i];
s[i]=s[j];
s[j]=temp;
}
}
}
return s;
}
public static int[] removedups(int s[])//remove dups from sorted array
{
Vector array=new Vector();
int l=0;
for(int i=0;i<s.length-1;i++)
{
if(s[i]!=s[i+1])
{
array.add(s[i]);
l++;
}
}
int[] temp=new int[array.size()];
for(int j=0;j<temp.length;j++)
{
temp[j]=Integer.parseInt(""+array.get(j));
}
return temp ;
}
}//end the program
Simpliest way is use sort and HashSet
public class SortClass {
public static void main(String[] args) {
//Define imput data
int[] a = {1, 2, 3, 4, 5};
int[] b = {1, 2, 3, 4, 5, 6};
int[] c = {1, 3, 7};
int[] d = {2, 3, 4, 8, 9, 10};
//Actual algorithm
List<Integer> all = new ArrayList<Integer>();
all.addAll(toList(a));
all.addAll(toList(b));
all.addAll(toList(c));
all.addAll(toList(d));
Collections.sort(all);
TreeSet<Integer> set = new TreeSet<Integer>();
set.addAll(all);
int[] sorted = toIntArray(all);
int[] sortedUniq = toIntArray(set);
//Output result
System.out.println("Sorted: " + Arrays.toString(sorted));
System.out.println("Sorted uniq: " + Arrays.toString(sortedUniq));
}
// We need pair of method to convert between `int[]` and `Collection<Integer>`
private static int[] toIntArray(Collection<Integer> all) {
int[] ints = new int[all.size()];
int i =0;
for (int val : all) {
ints[i] = val;
i++;
}
return ints;
}
private static Collection<? extends Integer> toList(int[] ints) {
ArrayList<Integer> list = new ArrayList<Integer>();
for (int i : ints) {
list.add(i);
}
return list;
}
}
But if performance is critical we can utilize the fact that input arrays already sorted and us merge sort:
public class SortClass {
public static void main(String[] args) {
int[] a = {1, 2, 3, 4, 5};
int[] b = {1, 2, 3, 4, 5, 6};
int[] c = {1, 3, 7};
int[] d = {2, 3, 4, 8, 9, 10};
//Prepare data structure
List<ArrayTail> all = new ArrayList<ArrayTail>();
add(all, new ArrayTail(a));
add(all, new ArrayTail(b));
add(all, new ArrayTail(c));
add(all, new ArrayTail(d));
int[] sorted = sort(all);
int[] sortedUniq = getUniq(sorted);
System.out.println("Sorted: " + Arrays.toString(sorted));
System.out.println("Sorted uniq: " + Arrays.toString(sortedUniq));
}
private static int[] getUniq(int[] sorted) {
Collection<Integer> result = new ArrayList<Integer>();
int current = sorted[0];
result.add(current);
for (int i : sorted){
if(i != current){
current = i;
result.add(i);
}
}
return toIntArray(result);
}
private static int[] sort(List<ArrayTail> all) {
int totalLength = 0;
for (ArrayTail tail : all){
totalLength+=tail.size();
}
int[] result = new int[totalLength];
int pos = 0;
while(!all.isEmpty()){
//Take smallest value from smallest array
ArrayTail smallest = all.get(0);
result[pos] = smallest.take();
pos++;
// remove array if no more elements in it
if(smallest.size() ==0){
all.remove(0);
} else {
// ensure that first element steel smallest
sortFirstElement(all);
}
}
return result;
}
// This is actually on step of bubble sort, but it
// works because all other list except may be first already sorted
private static void sortFirstElement(List<ArrayTail> all) {
for (int i = 0; i < all.size()-1; i++) {
if(all.get(i).get() > all.get(i+1).get()){
Collections.swap(all, i, i + 1);
} else {
break;
}
}
}
private static void add(List<ArrayTail> all, ArrayTail arrayTail) {
// all sorted here
all.add(0, arrayTail);
sortFirstElement(all);
// all sorted here, again
}
private static int[] toIntArray(Collection<Integer> all) {
int[] ints = new int[all.size()];
int i =0;
for (int val : all) {
ints[i] = val;
i++;
}
return ints;
}
// Simpl data structure representing tail of array
private static class ArrayTail {
private final int[] arr;
private int pos;
public ArrayTail(int[] arr) {
this.arr = arr;
this.pos = 0;
}
public int size() {
return arr.length - pos;
}
public int take() {
return arr[pos++];
}
public int get() {
return arr[pos];
}
}
}
As you can see code become more complex but possible work faster.
PS: fun thing is that bubble sort can be used in real life :)
TRY Using merge sort algorithm. wikipedia page here
For result 1, dump the contents of your 4 lists into a TreeSet. This will sort and remove duplicates from the set at the same time. Then get the array of the set.
For result 2, use array copy to copy all the numbers into 1 array and then sort that array using Arrays.sort(...). There is no need to try to merge them on your own due to the nature of the sorting algorithm which is O(nlog(n)). Quadrupling the size results in a multiplying factor of only 2.
I am trying to create method that creates new array only from the even numbers from another array. However, I do not understand why I have the right length (only with the number of the even numbers) of my output array, but I have 0s instead of the actual numbers.
I know that the problem is simple, but right now I am stuck with it.
import java.util.*;
public class test{
public static int [] myMethod(int []arr){
int [] temp;
int howManyEven = 0;
for(int i=0;i<arr.length;i++){
if(arr[i]%2==0){
howManyEven++;
}
}
temp = new int [howManyEven];
int evenNum = 0;
for(int i=0;i<temp.length;i++){
boolean even = false;
for(int j=0;j<arr.length;j++){
if(arr[j]%2==0){
even = true;
evenNum = arr[j];
}
}
if(!even){
temp[i]=evenNum;
}
}
return temp;
}
public static void main (String[]args){
int [] myArray = {5,5,8,9,7,4,4,2,3};
System.out.println(Arrays.toString(myMethod(myArray)));
}
}
In the second part of your myMethod, where there is nested for loop, your outer loop should iterate over arr. It can be simplified to below
temp = new int [howManyEven];
int j = 0;
for(int i=0;i<arr.length;i++){
if(arr[i]%2 == 0) {
temp[j++] = arr[i];
}
}
Better you can use java collections and finish the work in single loop
public static Integer[] myMethod(int []arr){ //notice the return type is Integer[] instead of int[]
List<Integer> evens = new ArrayList<Integer>();
for(int a : arr) {
if(a%2 == 0) {
evens.add(a);
}
}
return evens.toArray(new Integer[evens.size()]);
}
Look again at this:
if(!even){
temp[i]=evenNum;
}
I think you will notice yourself what's wrong.
Instead of processing the information twice for even numbers, you can create a List of integers which are 'even' and return that, or convert into primitive int[] and return that.
public static int[] myMethod(int[] arr) {
List<Integer> even = new ArrayList<Integer>();
for (int i = 0; i < arr.length; i++) {
if(arr[i]%2==0){
even.add(arr[i]);
}
}
int []result = new int[even.toArray().length];
Iterator it = even.iterator();
int count=0;
while(it.hasNext()){
result[count++]=(int)it.next();
}
return result;
}
public static void main(String[] args) {
int[] myArray = {5, 5, 8, 9, 7, 4, 4, 2, 3};
System.out.println(Arrays.toString(myMethod(myArray)));
}
output
run:
[8, 4, 4, 2]
BUILD SUCCESSFUL (total time: 0 seconds)
The easiest way would be myMethod should create a temparory list which collects the even numbers from the input array and then convert it to an output array containing only the even elements which should be returned to the caller
Working Example
public static void main(String... str) {
// results array has only even numbers
Integer[] results = myMethod(new int[]{5, 5, 8, 9, 7, 4, 4, 2, 3});
for(int i=0;i<results.length;i++)
System.out.println(results[i]); // print each even number
}
static Integer[] myMethod(int[] inputArray) {
List<Integer> temp = new ArrayList<Integer>();
for (int i = 0; i < inputArray.length; i++) {
if (inputArray[i] % 2 == 0) {
temp.add(inputArray[i]);
}
}
return temp.toArray(new Integer[5]);
}
Hope this code clarifies you well.