Wrong output while merging sorted arrays of equal length - java

I'm trying to merge 2 sorted arrays of equal length. However, I'm not getting the desired output.
Here is my code:
public static int[] mergeSorted(int[] arr1, int[] arr2){
int n = arr2.length;
int[] ans = new int[2*n];
int k = 0;
int i = 0;
int j = 0;
while(i < n && j < n){
if(arr1[i] <= arr2[j]){
ans[k] = arr1[i];
i++;
}
else{
ans[k] = arr2[j];
j++;
}
k++;
}
while(i < n){
ans[k] = arr1[i];
k++;
i++;
}
while(j < n){
ans[k] = arr2[j];
k++;
j++;
}
return ans;
}
public static void main(String[] args){
int[] arr1 = new int[]{1, 3, 5, 100, 34, 29};
int[] arr2 = new int[]{2, 4, 6, 9, 13, 300};
int[] ans = mergeSorted(arr1, arr2);
for(int el : ans)
System.out.print(el + " ");
}
Output:
1 2 3 4 5 6 9 13 100 34 29 300
Clearly, this is not correct. However, this code works for smaller inputs. Where am I going wrong?
EDIT: Test cases were wrong as they were not sorted. Code was fine.

For the merge operation to work, the two arrays you are merging should be in sorted order. The first array is not in sorted order:
int[] arr1 = new int[]{1, 3, 5, 100, 34, 29};
Change it to:
int[] arr1 = new int[]{1, 3, 5, 29, 34, 100};

Related

Add up each element in two uneven arrays in Java

Im Swedish so maybe I did give the wrong title.
I have two arrays of different size:
{2, 5, 10, 13}
{5, 7, 5, 22, 44, 75}
I want to add each element and put it in a third array.
So the result should be {7, 12, 15, 25, 44, 75}
I have manage to done some code.
I get an exeption of out of bounds.
I think the problem is that I canĀ“t add a non existing element.
But how can I solve it?
public static void main(String[] args) {
int[] samling = {1, 2, 4, 3, 8};
int[] samling2 = {1, 2, 4, 3, 8, 8, 3};
int[] svar = concateArrays(samling, samling2);
for(int i=0; i < svar.length; i++)
System.out.println("Ny Array " + svar[i]);
}
public static int[] concateArrays(int[] samling, int[] samling2)
{
int sum = samling.length + samling2.length;
int[] total = new int[sum];
for(int i=0; i < total.length; i++){
//if (samling2.length != 0) // || samling.length != 0)
total[i] = samling[i] + samling2[i];
}
return total;
}
The length of the output array shouldn't be the sum of lengths of the input arrays, it should be the length of the longer input array. And before accessing an element of either input array, you must check the current index i is a valid index of that array.
public static int[] concateArrays(int[] samling, int[] samling2)
{
int[] total = new int[Math.max(samling.length,samling2.length)];
for(int i=0; i < total.length; i++) {
total[i] = (i < samling.length ? samling[i] : 0) +
(i < samling2.length ? samling2[i] : 0);
}
return total;
}
You can use one loop to loop over both arrays simultaneously.
You first need to check which array is the longest, and make a new array:
int[] arr = new int[longest];
Then you need to walk over the array. In this example, I assume the latter array is always the longest.
for (int i = 0; i < samling2.length; i++) {
int totalValue = samling[i];
if (i < samling.length) {
totalValue += samling2[i];
}
arr[i] = totalValue;
}
You can make an array of length equal to max of the two arrays you have. Then you can add the elements from both arrays if the specific index exist in both arrays else simply copy the index from the array which contain that index.
See the following code to get a better picture
import java.io.*;
class GFG {
public static void main(String[] args) {
int[] samling = {1, 2, 4, 3, 8};
int[] samling2 = {1, 2, 4, 3, 8, 8, 3};
int[] svar = concateArrays(samling, samling2);
System.out.println("Ny Array :");
for(int i=0; i < svar.length; i++)
System.out.print(svar[i] + " ");
}
public static int[] concateArrays(int[] samling, int[] samling2)
{
int len = 0;
if (samling.length > samling2.length)
len = samling.length;
else
len = samling2.length;
int[] total = new int[len];
for(int i=0; i < len; i++){
if (i >= samling2.length) {
total[i] = samling[i];
}else if( i >= samling.length) {
total[i] = samling2[i];
}else{
total[i] = samling2[i] + samling[i];
}
}
return total;
}
}
Another variant, with no need for a conditional operation in each iteration of the copying loop:
public static int[] concateArrays(int[] samling, int[] samling2)
{
// max length of the two arrays
int maxLen = Math.max(samling.length,samling2.length);
// decide which of the inputs is shorter and which is longer
int[] shorter = maxLen == samling.length ? samling2 : samling;
int[] longer = maxLen == samling.length ? samling : samling2;
int[] total = new int[maxLen];
// add both as long as there are elements in the shorter
for(int i=0; i < shorter.length; i++) {
total[i] = shorter[i] + longer[i];
}
// copy the remainder of the longer
for(int i=shorter.length; i < longer.length; i++) {
total[i] = longer[i];
}
return total;
}
You can try this :
public static int[] concateArrays(int[] samling, int[] samling2)
{
int minLength = samling.length;
int[] array = null;
if (samling2.length > samling.length) {
array = samling2;
} else {
minLength = samling2.length;
array = samling;
}
for (int i = 0; i < minLength; i++) {
array[i] = samling[i] + samling2[i];
}
return array;
}

Using advanced for loop instead of for loop

I am a bit confused and I would need some clarification. Not too sure if I'm on the right track, hence this thread.
Here is my code that I want to decipher into advanced foreach loop.
int[] arrayA = {3, 35, 2, 1, 45, 92, 83, 114};
int[] arrayB = {4, 83, 5, 9, 114, 3, 7, 1};
int n = arrayA.length;
int m = arrayB.length;
int[] arrayC = new int[n + m];
int k = 0;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
if(arrayB[j] == arrayA[i])
{
arrayC[k++] = arrayA[i];
}
}
}
for(int i=0; i<l;i++)
System.out.print(arrayC[i] + " ");
System.out.println();
So far this is the point where I am stuck at:
int[] a = {3, 8, 2, 4, 5, 1, 6};
int[] b = {4, 7, 9, 8, 2};
int[] c = new int[a.length + b.length];
int k = 0;
for(int i : a)
{
for(int j : b)
{
if(a[i] == b[j])
{
c[k++] = a[i];
}
}
//System.out.println(c[i]);
}
for(int i=0; i<c.length;i++)
System.out.print(c[i] + " ");
System.out.println();
}
You are almost there
for(int i : a)
{
for(int j : b)
{
if(i == j)
{
c[k++] = i;
}
}
}
With for(int i : a) access the elements in the array a using i.
If a is {3, 8, 2, 4, 5, 1, 6}, then i would be 3,8,2,.. on each iteration and you shouldn't use that to index into the original array. If you do, you would get either a wrong number or a ArrayIndexOutOfBoundsException
Since you want to pick the numbers that are present in both the arrays, the length of array c can be max(a.length, b.length). So, int[] c = new int[Math.max(a.length, b.length)]; will suffice.
If you want to truncate the 0s at the end, you can do
c = Arrays.copyOf(c, k);
This will return a new array containing only the first k elements of c.
I would use a List and retainAll. And in Java 8+ you can make an int[] into a List<Integer> with something like,
int[] arrayA = { 3, 35, 2, 1, 45, 92, 83, 114 };
int[] arrayB = { 4, 83, 5, 9, 114, 3, 7, 1 };
List<Integer> al = Arrays.stream(arrayA).boxed().collect(Collectors.toList());
al.retainAll(Arrays.stream(arrayB).boxed().collect(Collectors.toList()));
System.out.println(al.stream().map(String::valueOf).collect(Collectors.joining(" ")));
Outputs
3 1 83 114
Alternatively, if you don't actually need the values besides displaying them, and you want to use the for-each loop (and less efficiently) like
int[] arrayA = { 3, 35, 2, 1, 45, 92, 83, 114 };
int[] arrayB = { 4, 83, 5, 9, 114, 3, 7, 1 };
for (int i : arrayA) {
for (int j : arrayB) {
if (i == j) {
System.out.print(i + " ");
}
}
}
System.out.println();
Temporary variables aren't indices in an array in foreach Loop. So in 0th iteration, i contains the 0th element of a, j contains the 0th element in b. Your attempt should be like this:
int[] a = {3, 8, 2, 4, 5, 1, 6};
int[] b = {4, 7, 9, 8, 2};
int[] c = new int[a.length + b.length];
int k = 0;
for(int i : a) {
for(int j : b) {
if(i == j) {
c[k++] = i;
}
} //System.out.println(c[i]);
}
Please note your c[] array will contain the order maintained in a[].

Find the last occurrence of an array Java?

I'm new to Java. I would like to get the index of the last occurrence in an array using loop. However, I don't understand why I can't.
This is the array:
{2, 3, 4, 5, 4, 5, 3}
I would like to get the index of the last 4 in it.
My code is:
public static void main(String args[]){
int[] nums = {2, 3, 4, 5, 4, 5, 3};
int pos4 = 0;
for (int k = nums.length -1; k >= 0; k--){
if (nums[k] == 4){
pos4 = k;
break;
}
System.out.print(pos4);
}
}
The result is: 00 ??
When I change to:
public static void main(String args[]){
int[] nums = {2, 3, 4, 5, 4, 5, 3};
int pos4 = 0;
for (int k = nums.length -1; k >= 0; k--){
if (nums[k] == 4){
break;
}
System.out.print(k);
}
}
I got 65 ???
However, when I print directly from the loop I get the index correctly:
public static void main(String args[]){
int[] nums = {2, 3, 4, 5, 4, 5, 3};
int pos4 = 0;
for (int k = nums.length -1; k >= 0; k--){
if (nums[k] == 4){
System.out.print(k);
break;
}
}
}
Can anyone tell me why? Thanks a lot!
Your first example is printing from within the loop. Once the condition was met you exited the loop and never printed out the final value.
public static void main(String args[]){
int[] nums = {2, 3, 4, 5, 4, 5, 3};
int pos4 = 0;
for (int k = nums.length -1; k >= 0; k--) {
if (nums[k] == 4){
pos4 = k;
break;
}
}
System.out.print(pos4); // moved outside of loop to print final value
}
How about using existing methods, and not reinventing the wheel? this one-liner solves the problem:
Integer[] array = { 2, 3, 4, 5, 4, 5, 3 };
int idx = Arrays.asList(array).lastIndexOf(4);
Your print statement is inside the loop. So it prints 0 twice, then when the result is found the break; skips over it. Try this...
int pos4 = 0;
for (int k = nums.length - 1; k >= 0; k--) {
if (nums[k] == 4) {
pos4 = k;
break;
}
}
System.out.print(pos4); // <== after loop

Java - Merge Two Arrays without Duplicates (No libraries allowed)

Need assistance with programming issue.
Must be in Java. Cannot use any libraries (Arraylist, etc.).
int[] a = {1, 2, 3, 4, 8, 5, 7, 9, 6, 0}
int[] b = {0, 2, 11, 12, 5, 6, 8}
Have to create an object referencing these two arrays in a method that merges them together, removes duplicates, and sorts them.
Here's my sort so far. Having difficulty combining two arrays and removing duplicates though.
int lastPos;
int index;
int temp;
for(lastPos = a.length - 1; lastPos >= 0; lastPos--) {
for(index = 0; index <= lastPos - 1; index++) {
if(a[index] > a[index+1]) {
temp = a[index];
a[index] = a[index+1];
a[index+1] = temp;
}
}
}
a method that merges them together, removes duplicates, and sorts them.
I suggest you break this down into helper methods (and slightly tweak the order of operations). Step 1, merge the two arrays. Something like,
static int[] mergeArrays(int[] a, int[] b) {
int[] c = new int[a.length + b.length];
for (int i = 0; i < a.length; i++) {
c[i] = a[i];
}
for (int i = 0; i < b.length; i++) {
c[a.length + i] = b[i];
}
return c;
}
Step 2, sort the new array (your existing sort algorithm is fine). Like,
static void sortArray(int[] a) {
for (int lastPos = a.length - 1; lastPos >= 0; lastPos--) {
for (int index = 0; index <= lastPos - 1; index++) {
if (a[index] > a[index + 1]) {
int temp = a[index];
a[index] = a[index + 1];
a[index + 1] = temp;
}
}
}
}
Finally, remove duplicates. Step 3a, count unique values. Assume they're unique, and decrement by counting adjacent (and equal) values. Like,
static int countUniqueValues(int[] c) {
int unique = c.length;
for (int i = 0; i < c.length; i++) {
while (i + 1 < c.length && c[i] == c[i + 1]) {
i++;
unique--;
}
}
return unique;
}
Then step 3b, take the unique count and build your result with the previous methods. Like,
public static int[] mergeDedupSort(int[] a, int[] b) {
int[] c = mergeArrays(a, b);
sortArray(c);
int unique = countUniqueValues(c);
int[] d = new int[unique];
int p = 0;
for (int i = 0; i < c.length; i++) {
d[p++] = c[i];
while (i + 1 < c.length && c[i] == c[i + 1]) {
i++;
}
}
return d;
}
Then you can test it with your arrays like
public static void main(String[] args) {
int[] a = { 1, 2, 3, 4, 8, 5, 7, 9, 6, 0 };
int[] b = { 0, 2, 11, 12, 5, 6, 8 };
int[] c = mergeDedupSort(a, b);
System.out.println(Arrays.toString(c));
}
And I get
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12]
Merge Two Arrays without Duplicates and Sort it (No libraries used).
Using an object.
public class MergeRemoveDupSort {
public int[] mergeRemoveDupSortIt(int[] a, int[] b) {
int [] c = mergeIt(a,b);
int [] d = removeIt(c);
int [] e = sortIt(d);
return e;
}
private int[] mergeIt(int[] a, int[] b) {
int[] c = new int[a.length + b.length];
int k=0;
for (int n : a) c[k++]=n;
for (int n : b) c[k++]=n;
return c;
}
private int[] removeIt(int[] c) {
int len=c.length;
for (int i=0;i<len-1;i++)
for (int j=i+1;j<len;j++)
if (c[i] == c[j]) {
for (int k=j;k<len-1;k++)
c[k]=c[k+1];
--len;
}
int [] r = new int[len];
for (int i=0;i<r.length;i++)
r[i]=c[i];
return r;
}
private int[] sortIt(int[] a) {
for(int index=0; index<a.length-1; index++)
for(int i=index+1; i<a.length; i++)
if(a[index] > a[i]){
int temp = a[index];
a[index] = a[i];
a[i] = temp;
}
return a;
}
public void printIt(int[] a) {
System.out.print("[");
for (int i=0;i<a.length;i++){
System.out.print(a[i]);
if (i!=a.length-1) System.out.print(",");
else System.out.print("]");
}
}
public static void main(String[] args) {
int[] a = {1, 2, 3, 4, 8, 5, 7, 9, 6, 0};
int[] b = {0, 2, 11, 12, 5, 6, 8};
MergeRemoveDupSort array = new MergeRemoveDupSort();
int [] r = array.mergeRemoveDupSortIt(a, b);
array.printIt(r);
}
}
You should use IntStream like this.
int[] a = {1, 2, 3, 4, 8, 5, 7, 9, 6, 0};
int[] b = {0, 2, 11, 12, 5, 6, 8};
int[] merged = IntStream
.concat(IntStream.of(a), IntStream.of(b))
.distinct()
.sorted()
.toArray();
System.out.println(Arrays.toString(merged));
Assuming that array a and array b are sorted, the following code will merge them into a third array merged_array without duplicates :
public static int[] get_merged_array(int[] a, int[] b, int a_size, int b_size)
{
int[] merged_array = new int[a_size + b_size];
int i = 0 , j = 0, x = -1;
for(; i < a_size && j < b_size;)
{
if(a[i] <= b[j])
{
merged_array[++x] = a[i];
++i;
}
else
{
if(merged_array[x] != b[j])
{
merged_array[++x] = b[j]; // avoid duplicates
}
++j;
}
}
--i; --j;
while(++i < a_size)
{
merged_array[++x] = a[i];
}
while(++j < b_size)
{
merged_array[++x] = b[j];
}
return merged_array;
}
Hope this may help, all the best :)
try{
int[] a = {1, 2, 3, 4, 8, 5, 7, 9, 6, 0};
int[] b = {0, 2, 11, 12, 5, 6, 8};
int[] c = new int[a.length+b.length];
int[] final = new int[a.length+b.length];
int i = 0;
for(int j : final){
final[i++] = -1;
}
i = 0;
for(int j : a){
c[i++] = j;
}
for(int j : b){
c[i++] = j;
}
boolean check = false;
for(int j = 0,k = 0; j < c.length; j++){
for(int l : fin){
if( l == c[j] )
check = true;
}
if(!check){
final[k++] = c[j];
} else check = false;
}
} catch(Exception ex){
ex.printStackTrace();
}
I prefer you to use Hashset for this cause it never allow duplicates
and there is another method in java 8 for arraylist to remove duplicates
after copying all elements to c follow this code
List<Integer> d = array.asList(c);
List<Integer> final = d.Stream().distinct().collect(Collectors.toList());
final.forEach(System.out::println());
This code is lot much better than previous one and you can again transform final to array like this
int array[] = new int[final.size()];
for(int j =0;j<final.size();j++){
array[j] = final.get(j);
}
Hope my work will be helpful .
Let me restate your question.
You want a program that takes two arbitrary arrays, merges them removing any duplicates, and sorts the result.
First of all, if you have access to any data structure, there are much better ways of doing this. Ideally, you would use something like a TreeSet.
However, assuming all you have access to is arrays, your options are much more limited. I'm going to go ahead and assume that each of the two arrays initially has no duplicates.
Let's assume the first array is of length m and the second array is of length n.
int[] array1; // length m
int[] array2; // length n
First, let's sort both arrays.
Arrays.sort(array1);
Arrays.sort(array2);
This assumes you have access to the Arrays class which is part of the standard Java Collections Framework. If not, any reasonable merge implementation (like MergeSort) will do the trick.
The sorts will take O(n log n + m log m) with most good sort implementations.
Next, let's merge the two sorted arrays. First, we need to allocate a new array big enough to hold all the elements.
int[] array3 = new int[size];
Now, we will need to insert the elements of array1 and array2 in order, taking care not to insert any duplicates.
int index=0, next=0, i=0, j=0;
int last = Integer.MAX_INT;
while(i < m || j < n) {
if(i == m)
next = array2[j++];
else if(j == n)
next = array1[i++];
else if(array1[i] <= array2[j])
next = array1[i++];
else
next = array2[j++];
if(last == next)
continue;
array3[index++] = next;
}
Now, you have your array. Just one problem - it could have invalid elements at the end. One last copy should take care of it...
int[] result = Arrays.copyOf(array3, index + 1);
The inserts and the final copy will take O(n + m), so the overall efficiency of the algorithm should be O(n log n + m log n).

Reversing an Array in Java [duplicate]

This question already has answers here:
How do I reverse an int array in Java?
(47 answers)
Closed 7 years ago.
If I have an array like this:
1 4 9 16 9 7 4 9 11
What is the best way to reverse the array so that it looks like this:
11 9 4 7 9 16 9 4 1
I have the code below, but I feel it is a little tedious:
public int[] reverse3(int[] nums) {
return new int[] { nums[8], nums[7], nums[6], nums[5], num[4],
nums[3], nums[2], nums[1], nums[0] };
}
Is there a simpler way?
Collections.reverse() can do that job for you if you put your numbers in a List of Integers.
List<Integer> list = Arrays.asList(1, 4, 9, 16, 9, 7, 4, 9, 11);
System.out.println(list);
Collections.reverse(list);
System.out.println(list);
Output:
[1, 4, 9, 16, 9, 7, 4, 9, 11]
[11, 9, 4, 7, 9, 16, 9, 4, 1]
If you want to reverse the array in-place:
Collections.reverse(Arrays.asList(array));
It works since Arrays.asList returns a write-through proxy to the original array.
If you don't want to use Collections then you can do this:
for (i = 0; i < array.length / 2; i++) {
int temp = array[i];
array[i] = array[array.length - 1 - i];
array[array.length - 1 - i] = temp;
}
I like to keep the original array and return a copy. This is a generic version:
public static <T> T[] reverse(T[] array) {
T[] copy = array.clone();
Collections.reverse(Arrays.asList(copy));
return copy;
}
without keeping the original array:
public static <T> void reverse(T[] array) {
Collections.reverse(Arrays.asList(array));
}
try this:
public int[] reverse3(int[] nums) {
int[] reversed = new int[nums.length];
for (int i=0; i<nums.length; i++) {
reversed[i] = nums[nums.length - 1 - i];
}
return reversed;
}
My input was:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
And the output I got:
12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
You could use org.apache.commons.lang.ArrayUtils :
ArrayUtils.reverse(array)
Or you could loop through it backeards
int[] firstArray = new int[]{1,2,3,4};
int[] reversedArray = new int[firstArray.length];
int j = 0;
for (int i = firstArray.length -1; i > 0; i--){
reversedArray[j++] = firstArray[i];
}
(note: I have not compiled this but hopefully it is correct)
In place reversal with minimum amount of swaps.
for (int i = 0; i < a.length / 2; i++) {
int tmp = a[i];
a[i] = a[a.length - 1 - i];
a[a.length - 1 - i] = tmp;
}
I would do something like this:
public int[] reverse3(int[] nums) {
int[] numsReturn = new int[nums.length()];
int count = nums.length()-1;
for(int num : nums) {
numsReturn[count] = num;
count--;
}
return numsReturn;
}
you messed up
int[] firstArray = new int[]{1,2,3,4};
int[] reversedArray = new int[firstArray.length];
int j = 0;
for (int i = firstArray.length -1; i >= 0; i--){
reversedArray[j++] = firstArray[i];
}
public void swap(int[] arr,int a,int b)
{
int temp=arr[a];
arr[a]=arr[b];
arr[b]=temp;
}
public int[] reverseArray(int[] arr){
int size=arr.length-1;
for(int i=0;i<size;i++){
swap(arr,i,size--);
}
return arr;
}
The following will reverse in place the array between indexes i and j (to reverse the whole array call reverse(a, 0, a.length - 1))
public void reverse(int[] a, int i , int j) {
int ii = i;
int jj = j;
while (ii < jj) {
swap(ii, jj);
++ii;
--jj;
}
}
In case you don't want to use a temporary variable, you can also do like this:
final int len = arr.length;
for (int i=0; i < (len/2); i++) {
arr[i] += arr[len - 1 - i]; // a = a+b
arr[len - 1 - i] = arr[i] - arr[len - 1 - i]; // b = a-b
arr[i] -= arr[len - 1 - i]; // a = a-b
}
This code would help:
int [] a={1,2,3,4,5,6,7};
for(int i=a.length-1;i>=0;i--)
System.out.println(a[i]);
you can send the original array to a method for example:
after that you create a new array to hold the reversed elements
public static void reverse(int[] a){
int[] reversedArray = new int[a.length];
for(int i = 0 ; i<a.length; i++){
reversedArray[i] = a[a.length -1 -i];
}

Categories