Comparing 2D arrays - java

Im trying to compare two 2D arrays by using this. But I keep getting "Arrays are not the same." even when they are the same.
int i;
int j = 0;
int k;
int l;
List<Integer> list = new ArrayList<Integer>();
List<Integer> list1 = new ArrayList<Integer>();
List<Integer> zero = new ArrayList<Integer>();
for ( i = 1; i <= 16; i++) {
list.add(i);
}
//System.out.println(list); //[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
Collections.shuffle(list.subList(1, 15));
System.out.println(list);
Collections.replaceAll(list, 16, 0);
System.out.println(list);
// System.out.println(list); //[11, 5, 10, 9, 7, 0, 6, 1, 3, 14, 2, 4, 15, 13, 12, 8]
int[][] a2 = new int[4][4];
int [][] a3 = new int[4][4];
for ( i = 0; i < 4; i++) {
for ( j = 0; j< 4; j++) {
a2[i][j] = list.get(i*4 + j);
a3[i][j] = list.get(i*4 + j);
}
}
for (int[] row : a2) {
System.out.print("[");
for ( int a : row)
System.out.printf("%4d", a);
System.out.println("]");
}
for (int[] row : a3) {
System.out.print("[");
for ( int a : row)
System.out.printf("%4d", a);
System.out.println("]");
}
boolean check1 = Arrays.equals(a2, a3);
if(check1 == false)
System.out.println("Arrays are not same.");
else
System.out.println("Both Arrays are same.");
I can't do it like this either.
boolean check1 = Arrays.equals(a2[i][j], a3[i][j]);

The first one does not work because a two-D int array is really an array of arrays (that is, an array of objects). The Arrays.equals() method for an array of objects uses equals() to test whether corresponding elements are equal. Unfortunately for your code, equals() for arrays is the default Object implementation: they are equal() only if they are the identical object. In your case, they are not.
In the second case, when you code Arrays.equals and pass two int values, the compiler can't match it to any signature of the Arrays class.
One way to check equality is to use deepEquals:
boolean check1 = Arrays.deepEquals(a2, a3);
Another way is to iterate the outer array explicitly:
boolean check1 = true;
for (int i = 0; check1 && i < a2.length; ++i) {
check1 = Arrays.equals(a2[i], a3[i]);
}

boolean check1 = Arrays.deepEquals(a2, a3);
is definitely a possibility. The implementation of that uses Object[], which may be appealing to you because it checks the types of the arrays you pass on-the-fly.
But if you want stronger typing and a little less overhead, you can write your own as follows.
import java.util.Arrays;
/**
* Operations on multi-dimensional arrays.
*
* #author stephen harrison
*/
public class ArrayUtils {
private ArrayUtils() {
// Static methods only
}
public static <T> boolean equals(final T[][] a, final T[][] b) {
if (a == b) {
return true;
}
if (a == null || b == null) {
return false;
}
if (a.length != b.length) {
return false;
}
for (int i = 0; i < a.length; ++i) {
if (!Arrays.equals(a[i], b[i])) {
return false;
}
}
return true;
}
public static <T> boolean equals(final T[][][] a, final T[][][] b) {
if (a == b) {
return true;
}
if (a == null || b == null) {
return false;
}
if (a.length != b.length) {
return false;
}
for (int i = 0; i < a.length; ++i) {
if (!equals(a[i], b[i])) {
return false;
}
}
return true;
}
}
The first equals on 2D arrays calls Arrays.equals(). The 3D version similarly calls the 2D one.
I hope that helps.

Related

How do I add two arraylists with an uneven amount of elements

I am trying to get the sum of two array lists elements with a different amount of elements in each one is a method. So far, I have been able to get the elements to add, but when the results print, it leaves out numbers because the array lists have different elements. Let's say array list a has 5 elements and array list b has 3 elements. The missing amounts in the array are supposed to be 0. So if a has {1, 2, 3, 4, 5} and b has {2, 3, 1}. The result should be {3, 5, 4, 4, 5}.
public static ArrayList<Integer> sum(ArrayList<Integer> a, ArrayList<Integer> b)
{
ArrayList <Integer> result = new ArrayList <Integer> ();
for(int i = 0; i < a.size(); i++) {
result.add(a.get(i) + b.get(i));
}
return result;
}
Take two lists add each elements one by one and store there sum in new list if there is no more element in any of the list take the remaining elements from the larger list and append at the end of the new list.
import java.util.*;
public class MainSum{
public static void main(String ... $){
var out = System.out;
List<Integer> a = new ArrayList<>(List.of(1, 2, 3, 4, 5));
List<Integer> b = new ArrayList<>(List.of(2, 3, 1));
List<Integer> result = MainSum.sum(a, b);
out.println(result);
}
public static List<Integer> sum(List<Integer> a, List<Integer> b){
List<Integer> result = new ArrayList<>();
for(int index =0 ;index<a.size() && index< b.size();index++)
result.add(a.get(index) + b.get(index));
if( a.size() != b.size())
result.addAll(a.size()>b.size()?a.subList(b.size(), a.size()):b.subList(a.size(), b.size()));
return result;
}
}
Output:
[3, 5, 4, 4, 5]
Note that you have 2 arrays in different sizes, so you should take it into consideration and your loop can't be always on a size, since it might be bigger than b size and then you try to access elements that aren't exist.
Something you can do is to loop over elements which are exist in both arrays, and then complete the rest. Suggestion:
public static ArrayList<Integer> sum(ArrayList<Integer> a, ArrayList<Integer> b) {
ArrayList result = new ArrayList();
int aSize = a.size();
int bSize = b.size();
for (int i = 0; i < Math.min(aSize, bSize); i++) { // Loop over elements that exist in both arrays
result.add(a.get(i) + b.get(i));
}
if (aSize > bSize) { // Complete missing from a
for (int i = aSize - bSize + 1; i < aSize; i++) {
result.add(a.get(i));
}
} else if (bSize > aSize) { // Complete missing from b
for (int i = bSize - aSize + 1; i < bSize; i++) {
result.add(b.get(i));
}
}
return result;
}
You have to make sure to iterate to the higher index, and make sure you don't run into a problem with a non existing index.
BiFunction<ArrayList<Integer>, Integer, Integer> getSafe =
(l, i ) -> i < l.size() ? l.get(i) : 0;
for (int i = 0; i < Math.max(list1.size(), list2.size(); i++) {
result.add(getSafe.apply(list1) + getSafe.apply(list1));
}
Or with an Iterator if you want to overengineer
Iterator<Integer> bothIterator = new Iterator<>() {
Iterator<Integer> it1 = list1.iterator();
Iterator<Integer> it2 = list2.iterator();
public boolean hasNext() {
return it1.hasNext() || it2.hasNext();
}
public Integer next() {
int result = it1.hasNext() ? it1.next();
result += it2.hasNext() ? it2.next() : 0;
return result;
}
}
int result = 0;
while (bothIterator.hasNext()) {
result += bothIterator.next();
}
Another approach can be based on customizing each list return values.
public class TestArrSum {
public static void main(String[] args)
{
List<Integer> a = List.of(1,2,3,4,5);
List<Integer> b = List.of(2,3,1);
List<Integer> result = sum(a,b);
result.forEach(System.out::println);
}
public static List<Integer> sum(List<Integer> a, List<Integer> b)
{
List<Integer> result = new ArrayList<Integer>();
for(int i=0;i<a.size() || i<b.size();i++)
{
result.add(getValue(a,i)+getValue(b,i));
}
return result;
}
public static int getValue(List<Integer> l,int i)
{
try
{
return l.get(i);
}
catch(ArrayIndexOutOfBoundsException e)
{
return 0;
}
}
}
Note: One advantage can be in terms of verbosity in case if need that method signature to contain more lists to be sum.
The same result can be obtained also with an intermediary data structure which latter will be transformed to List.
static class MyMap extends HashMap<Integer,Integer>
{
private static final long serialVersionUID = 1L;
MyMap()
{
super();
}
public void putKV(Integer key,Integer value)
{
Integer old = this.get(key);
if(old==null)
{
this.put(key, value);
}
else
{
this.put(key, old+value);
}
System.out.println(key+":"+value+":"+this.get(key));
}
public List<Integer> toList()
{
List<Integer> l = new ArrayList<Integer>();
for(int i=0; i<this.size();i++)
{
l.add(this.get(i));
}
return l;
}
}
Can be used as:
MyMap m = new MyMap();
for(int i=0;i<a.size();i++)
{
m.putKV(i, a.get(i));
}
for(int i=0;i<b.size();i++)
{
m.putKV(i, b.get(i));
}
List<Integer> resultM = m.toList();
resultM.forEach(k->System.out.println(k));

Finding the number of distinct pairs of integers that sum up to an integer

I am trying to count the numbers of pairs in an array such that each pair gives the sum of an integer!
I used the following code :
public static int SumPairs(Integer []input, int k){
Map<Integer, Integer> pairs = new HashMap<Integer, Integer>();
int tmp=0;
//System.out.println(pairs.toString());
for(int i=0;i<input.length;i++){
if(pairs.containsKey(input[i])){
System.out.println(pairs.containsKey(input[i]));
System.out.println(input[i] +", "+ pairs.get(input[i]));
input[i]=0;
tmp++;
}
else
pairs.put(k-input[i], input[i]);
}return tmp;
}
the problem is ; for example when my array is 1 2 2 2 3 4 4 4
and sum = 5
it compute as following
(4,1)
(4,1)
(4,1)
(3,2)
I want to prevent the method from using a number more than once !!
so the output will be
(4,1)
(3,2)
I hope this can help
def numberOfPairs(a, k):
# Let's do a o(n) approach by maintaining all the compliments of the K in a
# visited set
compliments = set()
result = set()
for v in a:
# See if the element is in the compliments set, if so thats the pair
if v in compliments:
result.add((v, k-v))
# If the element is not found in visited save the compliment of it in the visited set
else:
compliments.add(k-v)
return len(result)
I use a map storing values and their frequencies:
public static int SumPairs(Integer[] input, int k){
Map<Integer, Integer> frequencies = new HashMap<>();
int pairsCount = 0;
for(int i=0; i<input.length; i++){
int value = input[i];
int complement = k - input[i];
if(frequencies.containsKey(complement)){
int freq = frequencies.get(complement) - 1;
pairsCount++;
//System.out.println(value + ", " + complement);
if(freq == 0){
frequencies.remove(complement);
}else{
frequencies.put(complement, freq);
}
}else{
if(frequencies.containsKey(value)){
frequencies.put(value, frequencies.get(value) + 1);
}else{
frequencies.put(value, 1);
}
}
}
return pairsCount;
}
This works for all the test cases I could think of. Please add in the comment section any test case that this code fails so that I can fix it. If it works, please accept the solution.
public class DistinctPairs {
private static int count(int target, int... arr) {
int count = 0;
Set<String> seen = new HashSet<>();
Set<Integer> set = new HashSet<>();
for (int i = 0; i < arr.length; i++) {
int k = target - arr[i];
int[] pair = new int[]{k, arr[i]};
Arrays.sort(pair);
String s = Arrays.toString(pair);
if (set.contains(k) && !seen.contains(s)) {
count++;
seen.add(s);
// uncomment this print statement to print the distinct pairs
// System.out.println(s);
} else {
set.add(arr[i]);
}
}
return count;
}
// test suite and driver method
public static void main(String[] args) {
System.out.println(count(10, 1, 2, 3, 6, 7, 8, 9, 1) == 3);
System.out.println(count(47, 6, 1, 3, 46, 1, 3, 9) == 1);
System.out.println(count(9, 3, 2, 1, 45, 27, 6, 78, 9, 0) == 2);
System.out.println(count(9, 3, 3, 2, 1, 45, 27, 6, 78, 9, 0) == 2);
System.out.println(count(6, 1, 5, 7, -1) == 2);
System.out.println(count(6, 1, 5, 7, -1, 5) == 2);
System.out.println(count(2, 1, 1, 1, 1) == 1);
System.out.println(count(5, 1, 2, 2, 2, 3, 4, 4, 4) == 2);
System.out.println(count(8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4) == 1);
System.out.println(count(7, 1, 5, 66, 2, 3, 4, 7, 0, 2, 5) == 3);
System.out.println(count(5) == 0);
System.out.println(count(5, 1) == 0);
System.out.println(count(7, 3, 4) == 1);
}
}
Another approach can be to follow the classic solution of Two Sum Problem and add the pairs in a set as you find them, all this in the same pass. This set will be of a custom wrapper class with arr[i] and (target - arr[i]) as it's members and you'll need to override hashcode() and equals() methods in such a way that (a,b) is the same as (b,a). At the end simply return the size of the set. This approach will have the same time and space complexity in Big-O terms as the first approach.
int count(int target, int... nums) {
Set<Pair> uniPairs = new HashSet<>();
Set<Integer> seen = new HashSet<>();
for (int i = 0; i < nums.length; i++) {
int diff = target - nums[i];
if (seen.contains(diff)) {
Pair pair = new Pair(nums[i], diff);
uniPairs.add(pair);
}
seen.add(nums[i]);
}
return uniPairs.size();
}
class Pair {
int a;
int b;
public Pair (int a, int b) {
this.a = a;
this.b = b;
}
#Override
public boolean equals(Object obj) {
Pair pair2 = (Pair) obj;
return ((a == pair2.a) && (b == pair2.b)) || ((b == pair2.a) && (a == pair2.b));
}
#Override
public int hashCode() {
return Objects.hash(a, b) + Objects.hash(b, a);
}
}
public static int sumPairs(Integer[] input, int sum){
List<Integer> complementaries = new ArrayList<>(input.length);
int pairs = 0;
for(Integer number : input){
if(complementaries.contains(number)){
complementaries.remove(number);
pairs++;
}
else{
complementaries.add(sum-number);
}
}
return pairs;
}
Now it should work perfectly.
The complementaries array is used just for keeping track of the numbers needed for making the sum. If it contains the number it means that we iterated over its complementary before, so we can just add one pair and remove the number from the list of complementaries. Oherwise we add the complementary of the current number to the list without incresing the pairs counter.
The code takes an array and returns all possible pairs that have sum as specified. As the question asks to print number of pairs and not the pairs, the length of array divided by 2 would give the desired answer.
int notInArray(float a[],float m,int n)
{
int i,j,k;
for(i=0;i<n;i++)
{
if(a[i] == m)
return 0;
}
return 1;
}
int main() {
int i,j,k;
int n;
scanf("%d",&n); //Input the number of elements in array.
float arr[n];
for(i=0;i<n;i++)
scanf("%f",&arr[i]); //input the array elements
float copyArr = arr[0];
float m;
if (n == 0)
return 0;
scanf("%f",&m); //input the sum
float resArr[n];
int b;
int a=b=0;
for(i=0;i<n;i++)
{
for(j=i+1;j<n;j++)
{
if(arr[i]+arr[j]==m && notInArray(resArr,arr[i],n))
{
resArr[a++] = arr[i];
resArr[a++] = arr[j];
//printf("%.0f %.0f\n",arr[i],arr[j]);
}
}
}
printf("All possible pairs: \n");
for(i = 0;i<a;i+=2)
printf("%.0f %.0f\n",resArr[i],resArr[i+1]);
int len = (int)( sizeof(resArr) / sizeof(resArr[0]) )
printf("Number of such pairs: %d",len);
return 0;
}
public void distinctPairs(int[] arr, int k){
int length = arr.length;
int count = 0;
Map<Integer,Integer> pairs = new HashMap<Integer,Integer>();
for(int i=0;i<length;i++){
for(int j=i+1;j<length;j++){
if(arr[i]+arr[j] == k ){
if(!(pairs.containsKey(arr[j])&&pairs.containsValue(arr[i])))
pairs.put(arr[i], arr[j]);
}
}
}
count = pairs.size();
System.out.println("Pairs are "+pairs+" count = "+count);
}
This works for me. Steps I followed.
Check if sum of a pair is equal to required(k).
Check if the pair doesn't already exist in the map.
We can use the hashmap to store all values of the array. Then iterate over the array and check if the map contains (K - a[i] ). If the map contains then increment count and remove both keys from the map.
private int getDistinctPair(int k,int[] input){
HashMap<Integer,Integer> map = new HashMap<>();
int pairs = 0;
for (int i = 0; i < input.length-1; i++) {
map.put(input[i], input[i]);
}
for (int i = 0; i <input.length-1 ; i++) {
int diff = k - input[i];
if(map.containsKey(diff)){
pairs++;
map.remove(diff);
map.remove(input[i]);
}
}
return pairs;
}
You can slove by using below code:
def countPairs(arr, k):
possible_maps = []
for num in arr:
pair_matches = list(filter(lambda n: n + num == k, arr))
if len(pair_matches) > 0:
possible_maps += list(map(lambda nm: (num, nm), pair_matches))
return len(set(map(lambda pair: ','.join(str(n) for n in sorted(pair)), possible_maps)))
Hope this may help you.
My C# way to do this in a single loop with just another list to store temporary diff values.
private static int SumPairs(int[] arr, int sum)
{
Dictionary<int, int> frequency = new Dictionary<int, int>();
List<int> temp = new List<int>();
int count = 0;
foreach (int i in arr)
{
int diff = sum - i;
if (!frequency.ContainsKey(i))
{
if (temp.Contains(i))
{
frequency.Add(i, diff);
count++;
}
else
{
temp.Add(diff);
}
}
};
return count;
}
my C# implementation using Tuple
static List<Tuple<int,int>> GetUniquePairs(int[] arr, int sum)
{
Dictionary<Tuple<int, int>, int> kvp = new Dictionary<Tuple<int, int>, int>();
List<Tuple<int,int>> result = new List<Tuple<int,int>>();
int length = arr.Length;
for(int i = 0;i < length; i++)
{
int j = i + 1;
while (j < length)
{
if(arr[i]+arr[j] == sum)
{
Tuple<int, int> key = new Tuple<int, int>(arr[i], arr[j]);
if (!kvp.ContainsKey(key))
kvp.Add(key, 1);
}
j++;
}
}
var keys = kvp.Keys;
foreach(var k in keys)
{
result.Add(k);
}
return result;
}
The Simplest Solution of your problem of finding distinct pair:
public static int SumPairs(int[] input, int k) {
Map<Integer, Integer> pairs = new HashMap<Integer, Integer>();
int tmp = 0;
for (int data : input) {
if (pairs.containsKey(k - data) && pairs.get(k - data) == 0) {
tmp++;
pairs.put((k - data), pairs.get(k - data) + 1);
} else if (!pairs.containsKey(data)) {
pairs.put(data, 0);
}
}
return tmp;
}
It has been tested for 1 2 2 2 3 4 4 4 and sum = 5. Also for 4 4 4 4 4 4 4 4 4 4 4 4 4 4 and sum = 8.
If any confusion feel free to ask me. Cheers.
import java.util.HashSet;
public class DistinctPairs {
static int numberOfPairs(int[] arr,int k)
{
HashSet<String> s=new HashSet<String>();
int n=arr.length;
int sum=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
sum=arr[i]+arr[j];
if(i==j)
{
continue;
}
else
{
if(sum==k)
{
String l=String.valueOf("("+arr[i]+","+arr[j]+")");
StringBuilder sb=new StringBuilder(l);
String rl=sb.reverse().toString();
if(s.add(l)==false)
{
}
}
}
}
}
System.out.println(s.toString());
return s.size()/2;
}
public static void main(String args[])
{
int b[]={1,5,66,2,3,4,7,0,2,5};
int size=numberOfPairs(b,5);
System.out.println(size);
}
}

Finding the different element of 2 array

I've tried to print the non-intersection of sets between 2 array A and B. But, I have a problem how to print the elements on A different B.
Here is my sample code:
public class Array {
public static void main(String[] args) {
for (int i = 0; i <= arrA.length - 1; i++) {
arrA[i] = sc.nextInt();
}
for (int i = 0; i <= arrB.length - 1; i++) {
arrB[i] = sc.nextInt();
}
boolean x = true;
int y = 0;
for (int i = 0; i < arrA.length; i++) {
for (int j = 0; j < arrB.length; j++) {
if (arrA[i] == arrB[j]) {
arrTestA[i] = true;
}else y = arrA[i];
}
}
for (int i = 0; i < arrA.length; i++) {
x = x && arrTestA[i];
}
if (x) {
System.out.println("All the elements of A contained in B.");
}else {
System.out.println("There are elements on A different B.");
System.out.println("The elements of A which is not in B = "); //My Problem
}
}
}
To accomplish that you could use Collections and retainAll method.
E.g.:
List<Integer> arrTestA = new ArrayList<>();
List<Integer> arrTestB = new ArrayList<>();
[...]
List<Integer> common = new ArrayList<>(arrTestA);
common.retainAll(arrTestB);
List<Integer> diff = new ArrayList<>();
for(Integer element : arrTestA)
if(!common.contains(element))
diff.add(element);
[here you print out elements of diff as The elements of A which is not in B]
ETA: Non Collection attempt:
int[] arr1 = { 1, 11, 5, 9, 4, 3, 4, 8 };
int[] arr2 = { 1, 7, 5, 3, 4, 8 };
Arrays.sort(arr1);
Arrays.sort(arr2);
for (int i : arr1) {
boolean contains = false;
for (int j : arr2) {
if (i == j) {
contains = true;
break;
}
}
if (!contains)
System.out.println("Arr2 doesn't contain number: " + i);
}
...or the loop can look like this:
outer: for (int i : arr1) {
for (int j : arr2) {
if (i == j) {
continue outer;
}
}
System.out.println("Arr2 doesn't contain number: " + i);
}
This is only one way method, but hope you see the point.
ETA2:
In my approach, in fact, these Arrays don't have to be sorted. You can simply delete lines of code that are responsible for sorting.
You can use a Set (it requires additional space to store its elements, but the code is simple):
Integer[] a = {0, 1, 2};
Integer[] b = {1, 2, 3};
Set<Integer> setFromA = new HashSet<>(Arrays.asList(a));
for (int num : b) {
if (!setFromA.contains(num)) {
System.out.println(num);
}
}
The same using Java 8 Stream API:
Arrays.stream(b).filter(num -> !setFromA.contains(num)).forEach(System.out::println);
Also, you can save result into a new list (if you wish):
List<Integer> result = Arrays.stream(b)
.filter(num -> !setFromA.contains(num))
.collect(Collectors.toList());
The idea is to sort the two arrays and go through both of them. By sorting them you would not have to cross-check all elements
int[] arr1 = {1,3,5,6,7,4,8};
int[] arr2 = {1,2,5,6,9,4,8};
Arrays.sort(arr1);
Arrays.sort(arr2);
int j =0;
for(int i = 0; i < arr1.length; i++){
while(j < arr2.length && arr2[j] < arr1[i]){
System.out.println("number: " +arr2[j]);
j++;
}
if(arr2[j] != arr1[i]){
System.out.println("number: " +arr1[i]);
}else{
j++;
}
}
I would not suggest using list here because contains takes o(n) time complexity.
Use set as its contains take constant time:(In case you want to maintain order also, go for LinkedHashSet)
// store array b into a set
Set<Integer> setInts = new HashSet<>(Arrays.asList(B);
// traverse array a, and check if set contains currrent element
for(int e : A)
{
if(!setInts.contains(e))
System.out.println(e);
}

how can I get the result of addition and subtraction, with a recursive method that uses an ArrayList?

given a arraylist input, I have to create a recursive method that returns the sum of the values in the odd positions of the list from which the position of values are subtracted
For example:
private int method(ArrayList<Integer> list, int k)
{
int s = 0;
s = list.get(k);
if(k == list.size()) return s;
return s + method(k+1);
}
public int method(ArrayList<Integer> list)
{
return method(list,0);
}
(in main)
List<Integer> list = Arrays.asList(2, 5, 3, 7, 11, 1);
ArrayList<Integer> l2 = new ArrayList<>(list);
SumSub test = new SumSub(l2);
System.out.println(test.method(l2));
[2, 5, 3, 7, 11, 1] ---> 2-5+3-7+11-1=3 (the result that it should be showed)
but the result is always 22 and i can't understand why
Some pointers:
Give variables meaningful names, not k, s, list etc.
Declare collection interfaces (List) instead of implementation classes (ArrayList) where possible to improve the level of abstraction in your code.
Here an example of a recursive solution (untested):
private static int addOddAndSubtractEvenPositions(List<Integer> values, int position) {
// stop condition
if (position >= values.size()) {
return 0;
}
// recurse
int tailResult = addOddAndSubtractEvenPositions(values, position + 1);
// calculate
int currentValue = values.get(position);
if (position % 2 == 0) {
currentValue = -currentValue;
}
return currentValue + tailResult;
}
public static void main(String[] args) {
List<Integer> values = Arrays.asList(2, 5, 3, 7, 11, 1);
System.out.println(addOddAndSubtractEvenPositions(values, 0));
}
I haven't understood what the parameter k is used for
But a recursive method to subtract the elements in pair and then sum all the pairs can be:
public static int SumSub(ArrayList<Integer> list){
int result = 0;
int size = list.size();
if(list.size() > 2){
for(int i = 0; i < size; i++){
ArrayList<Integer> newList1 = new ArrayList<Integer>(list.subList(i, i+2));
result += SumSub(newList1);
i++;
}
} else {
result = list.get(0) - list.get(1);
}
return result;
}
}

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).

Categories