Union or intersection of Java Sets - java

What is the simplest way to make a union or an intersection of Sets in Java? I've seen some strange solutions to this simple problem (e.g. manually iterating the two sets).

The simplest one-line solution is this:
set1.addAll(set2); // Union
set1.retainAll(set2); // Intersection
The above solution is destructive, meaning that contents of the original set1 my change.
If you don't want to touch your existing sets, create a new set:
var result = new HashSet<>(set1); // In Java 10 and above
Set<Integer> result = new HashSet<>(set1); // In Java < 10
result.addAll(set2); // Union
result.retainAll(set2); // Intersection

While guava for sure is neater and pretty much standard, here's a non destructive way to do union and intersect using only standard Java
Set s1 = Set.of(1,2,3);
Set s2 = Set.of(3,4,5);
Set union = Stream.concat(s1.stream(),s2.stream()).collect(Collectors.toSet());
Set intersect = s1.stream().filter(s2::contains).collect(Collectors.toSet());

You can achieve this using Google's Guava library. The following explanation is given below with the help of an example:
// Set a
Set<String> a = new HashSet<String>();
a.add("x");
a.add("y");
a.add("z");
// Set b
Set<String> b = new HashSet<String>();
b.add("x");
b.add("p");
b.add("q");
Now, Calculating Intersection of two Set in Java:
Set<String> intersection = Sets.intersection(a, b);
System.out.printf("Intersection of two Set %s and %s in Java is %s %n",
a.toString(), b.toString(), intersection.toString());
Output: Intersection of two Set [z, y, x] and [q, p, x] in Java is [x]
Similarly, Calculating Union of two Set in Java:
Set<String> union = Sets.union(a, b);
System.out.printf("Union of two Set %s and %s in Java is %s %n",
a.toString(), b.toString(), union.toString());
Output: Union of two Set [z, y, x] and [q, p, x] in Java is [q, p, x, z, y]
You can read more about guava library at https://google.github.io/guava/releases/18.0/api/docs/
In order to add guava library to your project, You can see https://stackoverflow.com/a/4648947/8258942

import java.util.*;
public class sets {
public static void swap(int array[], int a, int b) { // Swap function for sorting
int temp = array[a];
array[a] = array[b];
array[b] = temp;
}
public static int[] sort(int array[]) { // sort function for binary search (Selection sort)
int minIndex;
int j;
for (int i = 0; i < array.length; i++) {
minIndex = i;
for (j = i + 1; j < array.length; j++) {
if (array[minIndex] > array[j])
minIndex = j;
}
swap(array, minIndex, i);
}
return array;
}
public static boolean search(int array[], int search) { // Binary search for intersection and difference
int l = array.length;
int mid = 0;
int lowerLimit = 0, upperLimit = l - 1;
while (lowerLimit <= upperLimit) {
mid = (lowerLimit + upperLimit) / 2;
if (array[mid] == search) {
return true;
} else if (array[mid] > search)
upperLimit = mid - 1;
else if (array[mid] < search)
lowerLimit = mid + 1;
}
return false;
}
public static int[] append(int array[], int add) { // To add elements
int newArray[] = new int[array.length + 1];
for (int i = 0; i < array.length; i++) {
newArray[i] = array[i];
}
newArray[array.length] = add;
newArray = sort(newArray);
return newArray;
}
public static int[] remove(int array[], int index) { // To remove duplicates
int anotherArray[] = new int[array.length - 1];
int k = 0;
if (array == null || index < 0 || index > array.length) {
return array;
}
for (int i = 0; i < array.length; i++) {
if (index == i) {
continue;
}
anotherArray[k++] = array[i];
}
return anotherArray;
}
public static void Union(int A[], int B[]) { // Union of a set
int union[] = new int[A.length + B.length];
for (int i = 0; i < A.length; i++) {
union[i] = A[i];
}
for (int j = A.length, i = 0; i < B.length || j < union.length; i++, j++) {
union[j] = B[i];
}
for (int i = 0; i < union.length; i++) {
for (int j = 0; j < union.length; j++) {
if (union[i] == union[j] && j != i) {
union = remove(union, j); // Removing duplicates
}
}
}
union = sort(union);
System.out.print("A U B = {"); // Printing
for (int i = 0; i < union.length; i++) {
if (i != union.length - 1)
System.out.print(union[i] + ", ");
else
System.out.print(union[i] + "}");
}
}
public static void Intersection(int A[], int B[]) {
int greater = (A.length > B.length) ? (A.length) : (B.length);
int intersect[] = new int[1];
int G[] = (A.length > B.length) ? A : B;
int L[] = (A.length < B.length) ? A : B;
for (int i = 0; i < greater; i++) {
if (search(L, G[i]) == true) { // Common elements
intersect = append(intersect, G[i]);
}
}
for (int i = 0; i < intersect.length; i++) {
for (int j = 0; j < intersect.length; j++) {
if (intersect[i] == intersect[j] && j != i) {
intersect = remove(intersect, j); // Removing duplicates
}
}
}
System.out.print("A ∩ B = {"); // Printing
for (int i = 1; i < intersect.length; i++) {
if (i != intersect.length - 1)
System.out.print(intersect[i] + ", ");
else
System.out.print(intersect[i] + "}");
}
}
public static void difference(int A[], int B[]) {
int diff[] = new int[1];
int G[] = (A.length > B.length) ? A : B;
int L[] = (A.length < B.length) ? A : B;
int greater = G.length;
for (int i = 0; i < greater; i++) {
if (search(L, G[i]) == false) {
diff = append(diff, G[i]); // Elements not in common
}
}
for (int i = 0; i < diff.length; i++) {
for (int j = 0; j < diff.length; j++) {
if (diff[i] == diff[j] && j != i) {
diff = remove(diff, j); // Removing duplicates
}
}
}
System.out.println("Where A is the larger set, and B is the smaller set.");
System.out.print("A - B = {"); // Printing
for (int i = 1; i < diff.length; i++) {
if (i != diff.length - 1)
System.out.print(diff[i] + ", ");
else
System.out.print(diff[i] + "}");
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter the operation");
String operation = sc.next().toLowerCase();
System.out.println("Enter the length of the first set.");
int l1 = sc.nextInt();
System.out.println("Enter the length of the second set.");
int l2 = sc.nextInt();
int A[] = new int[l1];
int B[] = new int[l2];
System.out.println("Enter the elements of the first set.");
System.out.print("A = ");
for (int i = 0; i < l1; i++) {
A[i] = sc.nextInt();
}
System.out.println("Enter the elements of the second set.");
System.out.print("B = ");
for (int i = 0; i < l2; i++) {
B[i] = sc.nextInt();
}
A = sort(A); // Sorting the sets before passing
B = sort(B);
sc.close();
switch (operation) {
case "union":
Union(A, B);
break;
case "intersection":
Intersection(A, B);
break;
case "difference":
difference(B, A);
break;
default:
System.out.println("Invalid Operation");
}
}
}

When I think of union and intersection, it is in the first loop an operation on sets, i.e. a map
            Set<T>  x  Set<T>  →  Set<T>Not clear, why it would appear in Java design that shirtsleeved.
static <T> Set<T> union(Set<T> a, Set<T> b)
{
Set<T> res = new HashSet<T>(a);
res.addAll(b);
return res;
}
static <T> Set<T> intersection(Set<T> a, Set<T> b)
{
Set<T> res = new HashSet<T>(a);
res.retainAll(b);
return res;
}

Related

Finding sorted subarrays in array

I am working on sorting algorithms and I am trying to improve mergeSort by locating already sorted subArrays.
public static void mergeSort(int[] array)
{
if(array == null)
{
return;
}
if(array.length > 1)
{
int mid = array.length / 2;
// left
int[] left = new int[mid];
for(int i = 0; i < mid; i++)
{
left[i] = array[i];
}
//right
int[] right = new int[array.length - mid];
for(int i = mid; i < array.length; i++)
{
right[i - mid] = array[i];
}
//recursively calls
mergeSort(left);
mergeSort(right);
int i = 0;
int j = 0;
int k = 0;
// left and right merged
while(i < left.length && j < right.length)
{
if(left[i] < right[j])
{
array[k] = left[i];
i++;
}
else
{
array[k] = right[j];
j++;
}
k++;
}
// left overs
while(i < left.length)
{
array[k] = left[i];
i++;
k++;
}
while(j < right.length)
{
array[k] = right[j];
j++;
k++;
}
}
}
What you are looking for is called natural merge sort. Before you start with sorting the dataset you will do one run to identify all the presorted data. The mergesort itself stays the same.
I found some example code for you at: happycoders
package eu.happycoders.sort.method.mergesort;
import eu.happycoders.sort.method.Counters;
import eu.happycoders.sort.method.SortAlgorithm;
/**
* Natural merge sort implementation for performance tests.
*
* #author Sven Woltmann
*/
public class NaturalMergeSort implements SortAlgorithm {
#Override
public void sort(int[] elements) {
int numElements = elements.length;
int[] tmp = new int[numElements];
int[] starts = new int[numElements + 1];
// Step 1: identify runs
int runCount = 0;
starts[0] = 0;
for (int i = 1; i <= numElements; i++) {
if (i == numElements || elements[i] < elements[i - 1]) {
starts[++runCount] = i;
}
}
// Step 2: merge runs, until only 1 run is left
int[] from = elements;
int[] to = tmp;
while (runCount > 1) {
int newRunCount = 0;
// Merge two runs each
for (int i = 0; i < runCount - 1; i += 2) {
merge(from, to, starts[i], starts[i + 1], starts[i + 2]);
starts[newRunCount++] = starts[i];
}
// Odd number of runs? Copy the last one
if (runCount % 2 == 1) {
int lastStart = starts[runCount - 1];
System.arraycopy(from, lastStart, to, lastStart,
numElements - lastStart);
starts[newRunCount++] = lastStart;
}
// Prepare for next round...
starts[newRunCount] = numElements;
runCount = newRunCount;
// Swap "from" and "to" arrays
int[] help = from;
from = to;
to = help;
}
// If final run is not in "elements", copy it there
if (from != elements) {
System.arraycopy(from, 0, elements, 0, numElements);
}
}
private void merge(int[] source, int[] target, int startLeft,
int startRight, int endRight) {
int leftPos = startLeft;
int rightPos = startRight;
int targetPos = startLeft;
// As long as both arrays contain elements...
while (leftPos < startRight && rightPos < endRight) {
// Which one is smaller?
int leftValue = source[leftPos];
int rightValue = source[rightPos];
if (leftValue <= rightValue) {
target[targetPos++] = leftValue;
leftPos++;
} else {
target[targetPos++] = rightValue;
rightPos++;
}
}
// Copy the rest
while (leftPos < startRight) {
target[targetPos++] = source[leftPos++];
}
while (rightPos < endRight) {
target[targetPos++] = source[rightPos++];
}
}
#Override
public void sort(int[] elements, Counters counters) {
// Not implemented
}
}

returning null when the array is outside the desired range

Say I have a function that produces an array:
static long[] solveEquationB(int x, int j)
{
long[] e = new long[j];
for (int i = 1; i < j; i++)
{
x = 1.0*x/(2.0) + 3 ;
e[i] = x;
}
return e;
}
How can I get the output to produce null when j < 0?
Test j before creating the array:
static long [] solveEquationB (int x, int j)
{
long[] e = null;
if (j >= 0) { // or perhaps > 0 if you don't want to return an empty array
e = new long[j];
for (int i = 1; i < j; i++)
{
x = 1.0*x/(2.0) + 3 ;
e[i] = x;
}
}
return e;
}
You can just add one line as a ternary operator check to the above code. Here's the modified code:
static long[] solveEquationB(int x, int j) {
long[] e = j > 0? new long[j]: null;
for (int i = 1; i < j; i++) {
x = 1.0*x/(2.0) + 3 ;
e[i] = x;
}
return e;
}

Sorting multidimensional array without sort method?

I was tasked with creating a 2D array (10-by-10), filling it with random numbers (from 10 to 99), and other tasks. I am, however, having difficulty sorting each row of this array in ascending order without using the array sort() method.
My sorting method does not sort. Instead, it prints out values diagonally, from the top leftmost corner to the bottom right corner. What should I do to sort the numbers?
Here is my code:
public class Program3
{
public static void main(String args[])
{
int[][] arrayOne = new int[10][10];
int[][] arrayTwo = new int[10][10];
arrayTwo = fillArray(arrayOne);
System.out.println("");
looper(arrayTwo);
System.out.println("");
sorter(arrayTwo);
}
public static int randomRange(int min, int max)
{
// Where (int)(Math.random() * ((upperbound - lowerbound) + 1) + lowerbound);
return (int)(Math.random()* ((max - min) + 1) + min);
}
public static int[][] fillArray(int x[][])
{
for (int row = 0; row < x.length; row++)
{
for (int column = 0; column < x[row].length; column++)
{
x[row][column] = randomRange(10,99);
System.out.print(x[row][column] + "\t");
}
System.out.println();
}
return x;
}
public static void looper(int y[][])
{
for (int row = 0; row < y.length; row++)
{
for (int column = 0; column < y[row].length; column++)
{
if (y[row][column]%2 == 0)
{
y[row][column] = 2 * y[row][column];
if (y[row][column]%10 == 0)
{
y[row][column] = y[row][column]/10;
}
}
else if (y[row][column] == 59)
{
y[row][column] = 99;
}
System.out.print(y[row][column] + "\t");
}
System.out.println();
}
//return y;
}
public static void sorter(int[][] z)
{
int temp = 0;
int tempTwo = 0;
int lowest;
int bravo = 0;
int bravoBefore = -1;
for (int alpha = 0; alpha < z.length; alpha++)
{
//System.out.println(alpha + "a");
lowest = z[alpha][bravoBefore + 1];
bravoBefore++;
for (bravo = alpha + 1; bravo < z[alpha].length; bravo++)
{
//System.out.println(alpha + "b");
temp = bravo;
if((z[alpha][bravo]) < lowest)
{
temp = bravo;
lowest = z[alpha][bravo];
//System.out.println(lowest + " " + temp);
//System.out.println(alpha + "c" + temp);
tempTwo = z[alpha][bravo];
z[alpha][bravo] = z[alpha][temp];
z[alpha][temp] = tempTwo;
//System.out.println(alpha + "d" + temp);
}
}
System.out.print(z[alpha][bravoBefore] + "\t");
}
/*
for (int alpha = 0; alpha < z.length; alpha++)
{
for (int bravo = 0; bravo < z.length - 1; bravo++)
{
if(Integer.valueOf(z[alpha][bravo]) < Integer.valueOf(z[alpha - 1][bravo]))
{
int[][] temp = z[alpha - 1][bravo];
z[alpha-1][bravo] = z[alpha][bravo];
z[alpha][bravo] = temp;
}
}
}
*/
}
}
for(int k = 0; k < arr.length; k++)
{
for(int p = 0; p < arr[k].length; p++)
{
least = arr[k][p];
for(int i = k; i < arr.length; i++)
{
if(i == k)
z = p + 1;
else
z = 0;
for(;z < arr[i].length; z++)
{
if(arr[i][z] <= small)
{
least = array[i][z];
row = i;
col = z;
}
}
}
arr[row][col] = arr[k][p];
arr[k][p] = least;
System.out.print(arr[k][p] + " ");
}
System.out.println();
}
Hope this code helps . Happy coding
let x is our unsorted array;
int t1=0;
int i1=0;
int j1=0;
int n=0;
boolean f1=false;
for(int i=0;i<x.length;i++){
for(int j=0;j<x[i].length;j++){
t1=x[i][j];
for(int m=i;m<x.length;m++){
if(m==i)n=j+1;
else n=0;
for(;n<x[m].length;n++){
if(x[m][n]<=t1){
t1=x[m][n];
i1=m;
j1=n;
f1=true;
}
}
}
if(f1){
x[i1][j1]=x[i][j];
x[i][j]=t1;
f1=false;
}
}
}
//now x is sorted; "-";

I am trying to write a quickSort method as part of an assignment, but I keep getting a StackOverflow error in Java

This is the code for my sorting attempt. After running for about ten minutes in Eclipse's debugger mode, I got a lot of StackOverFlow errors. This was my output display:
Exception in thread "main" java.lang.StackOverflowError
at TestSorter.Tester.sort(Tester.java:6)
... (x112 repetitions of at TestSorter.Tester.sort(Tester.java:49))
at TestSorter.Tester.sort(Tester.java:49)
public static int[] sort(int[] a) {
int prod = (a.length)/2, b = lessThan(a, prod), c = greaterThan(a, prod), d = equalTo(a, prod);
int[] first, last, mid;
first = new int[b];
last = new int[c];
mid = new int[d];
int[] fina = new int[a.length];
int f = 0, l = 0, m = 0;
if (isSorted(a))
return a;
for (int x = 0; x < a.length; x++) {
if (a[x] < prod) {
first[f] = a[x];
f++;
}
else if (a[x] > prod) {
last[l] = a[x];
l++;
}
else if (a[x] == prod) {
mid[m] = a[x];
m++;
}
}
if (m == a.length)
return a;
first = sort(first);
last = sort(last);
for (int x = 0; x < b; x++) {
fina[x] += first[x];
}
for (int x = 0; x < d; x++) {
fina[x + b] = mid[x];
}
for (int x = 0; x < c; x++) {
fina[x + b + c] = last[x];
}
return fina;
}
My support methods are as follows:
private static int lessThan(int[] a, int prod) {
int less = 0;
for (int x = 0; x < a.length; x++) {
if (a[x] < prod) {
less++;
}
}
return less;
}
private static int greaterThan(int[] a, int prod) {
int greater = 0;
for (int x = 0; x < a.length; x++) {
if (a[x] > prod) {
greater++;
}
}
return greater;
}
private static int equalTo(int[] a, int prod) {
int equal = 0;
for (int x = 0; x < a.length; x++) {
if (a[x] == prod) {
equal++;
}
}
return equal;
}
private static boolean isSorted(int[] a) {
for (int x = 0; x < a.length - 1; x++) {
if (a[x] > a[x + 1])
return false;
}
return true;
}
Presumably the trouble is that your "prod" is not within the domain of your array. Thus either "first" or "last" is the same size as the input array, and you have an infinite recursion. Try setting prod to be an element in the array you are trying to sort.
THREE POINTS:
The pord should be the mid-element of the array, NOT the half of the array's length.
So, it should be prod =a[(a.length) / 2],
NOT prod =(a.length) / 2
If the array first only have 1 element, it does not need invoke the method sort any more.
Also the last.
So, add if statement:
if (1 < first.length) {
first = sort(first);
}
When you append the element of last to fina, the index should be x+b+d, it means first elements(b) + mid elements(d). NOT x+b+c.
So, change fina[x + b + c] = last[x]; to fina[x + b + d] = last[x];
Well, the method sort maybe like this:
public static int[] sort(int[] a) {
int prod =a[(a.length) / 2], b = lessThan(a, prod), c = greaterThan(a,
prod), d = equalTo(a, prod);
int[] first, last, mid;
first = new int[b];
last = new int[c];
mid = new int[d];
int[] fina = new int[a.length];
int f = 0, l = 0, m = 0;
if (isSorted(a) )
return a;
for (int x = 0; x < a.length; x++) {
if (a[x] < prod) {
first[f] = a[x];
f++;
} else if (a[x] > prod) {
last[l] = a[x];
l++;
} else if (a[x] == prod) {
mid[m] = a[x];
m++;
}
}
if (m == a.length)
return a;
if (1 < first.length) {
first = sort(first);
}
if (1 < last.length) {
last = sort(last);
}
for (int x = 0; x < b; x++) {
fina[x] += first[x];
}
for (int x = 0; x < d; x++) {
fina[x + b] = mid[x];
}
for (int x = 0; x < c; x++) {
fina[x + b + d] = last[x];
}
return fina;
}

null pointer exception sorting merged array list

I have been trying to figure out how to properly print the return of my method.
When the program prints the return of my method, I am giving a nullPointerException error on line 45(the line where i am trying to print the method).
*I did try to make the return to the method static so it is accessible.
How do I initialize the "answer" variable so that i can print it outside of my method?
Thank you in advance
import javax.swing.JOptionPane;
public class ListSortMerge {
static int[]answer;
public static void main(String[] args) {
int v1 = 0, v2 = 0;
for(int c = 0; c <= 1; c++) {
String values = JOptionPane.showInputDialog("How many values would you like to store in list "+(c+1)+"?");
if (c==0) {
v1 = Integer.parseInt(values);
}
else{
v2 = Integer.parseInt(values);
}
}
int[] numbers1 = new int[v1];
int[] numbers2 = new int[v2];
merge(numbers1,numbers2);
int i;
System.out.println("\nList 1 before the sort");
System.out.println("--------------------");
for(i = 0; i < (v1); i++) {
System.out.println(numbers1[i]);
}
System.out.println("\nList 2 before the sort");
System.out.println("--------------------");
for(i = 0; i < (v2); i++) {
System.out.println(numbers2[i]);
}
System.out.println("\nList after the sort");
System.out.println("--------------------");
for(i = 0; i < (v1+v2); i++) {
System.out.println(answer[i]);
}
}
public static int[] merge(int[] a, int[] b) {
int[] answer = new int[a.length + b.length];
for(int c = 0; c < (a.length); c++)
{
String aVal1 = JOptionPane.showInputDialog("Input list 1 value " +(c+1));
a[c] = Integer.parseInt(aVal1);
}
for ( int c = 0; c < (b.length); c++){
String aVal2 = JOptionPane.showInputDialog("Input list 2 value " +(c + 1));
b[c] = Integer.parseInt(aVal2);
}
int i = 0, j = 0, k = 0;
while (i < a.length && j < b.length)
{
if (a[i] < b[j])
answer[k++] = a[i++];
else
answer[k++] = b[j++];
}
while (i < a.length)
answer[k++] = a[i++];
while (j < b.length)
answer[k++] = b[j++];
return answer;
}
}
You have two different answer variables: one is a local variable in the merge function and another is a static field in the class. You never initialize the second one.

Categories