Print Maximum Frequent Element - java

public class TestClass {
private static int maxOccurence(int a[]) {
int max = 0;
int count = 0;
for (int i = 0; i < a.length - 1; i++) {
for (int j = i + 1; j < a.length; j++) {
if (a[i] == a[j]) {
count++;
max = Math.max(max, count);
}
}
count = 0;
}
return max + 1;
}
public static void main(String[] args) {
int a[] = { 3, 3, 4, 2, 4, 4, 2, 4, 4 };
System.out.println(maxOccurence(a));
}
}
This program counts, for each element of an array, the number of times that the element appears; then, it returns the maximum value. In my example, the program prints "5", since element "4" occurs 5 times. How can the element also be printed? In this case, the output of the program would be "4 : 5".

In Java you can write
int[] a = {3, 3, 4, 2, 4, 4, 2, 4, 4};
Map<Integer, Long> countMap = IntStream.of(a).boxed()
.collect(groupingBy(i -> i, counting()));
Map.Entry<Integer, Long> first = countMap.entrySet().stream()
.sorted(comparing(Map.Entry<Integer, Long>::getValue).reversed())
.findFirst().orElseThrow(AssertionError::new);
System.out.println(first.getKey()+":"+first.getValue());
This prints
4:5

[ANSWERED WHEN TAG WAS C#]
It seems to be a nice solution :
public static class TestClass
{
public static void PrintMaxOccurence(int[] a)
{
var maxOccurenceGroup = a.ToList().GroupBy(s => s)
.OrderByDescending(s => s.Count())
.First();
Console.WriteLine(maxOccurenceGroup.Key + " occured " + maxOccurenceGroup.Count() + " times.");
Console.ReadKey();
}
}
class Program
{
public static void main(String[] args)
{
var a = new[] { 3, 3, 4, 2, 4, 4, 2, 4, 4 };
TestClass.PrintMaxOccurence(a);
}
}
Feel free to ask help if needed.

In C# you have to declare variable as int[] a; but not int a[];
static void Main(string[] args)
{
int[] a = new[] { 3, 3, 4, 2, 4, 4, 2, 4, 4 };
PrintMaxOccurence(a);
}
private static void PrintMaxOccurence(int[] a)
{
var result = (from item in a
group item by item into x
orderby x.Count() descending
select new { Element = x.Key, OccurenceCount = x.Count() }).First();
Console.WriteLine("{0} : {1}", result.Element, result.OccurenceCount);
}

We can as well solve the problem using hashtable as follows.
import java.util.Hashtable;
public class MaxOcurr {
public static void main(String[] args) {
Hashtable<Integer,Integer> table = new Hashtable<Integer, Integer>();
int maxCount = 0;
int maxValue = -1;
int a[] = {1,3,2,5,3,6,8,8,8,6,6,7,5,6,4,5,6,4,6,4,1,3,2,6,9,2};
for (int i = 0; i < a.length; i++) {
if (table.containsKey(a[i])) {
table.put(a[i], table.get(a[i])+1);
} else {
table.put(a[i],1);
}
if (table.get(a[i]) > maxCount) {
maxCount = table.get(a[i]);
maxValue = a[i];
}
}
System.out.println(maxValue +":"+ maxCount);
}
}

Related

How to replace recursion in my code on Java?

This code calculates the number of permutations for four points by 3 (no repetitions).
Arranged with recursion, but this is awkward for me.
import java.util.*;
public class Main {
static int TOTAL_POINTS = 4, POINTS_ON_LINE = 3;
static int[] temp = new int[POINTS_ON_LINE];
public static void main(String[] args) {
int[] points = new int[]{1,2,3,4};
System.out.println("no repetitions:");
p1(0,0, points);
}
static void p1(int nowPosition, int sizeArray, int[] points) {
if (nowPosition == POINTS_ON_LINE) {
System.out.println("Output:");
System.out.println(Arrays.toString(temp));
} else {
for(int i = sizeArray + 1; i <= TOTAL_POINTS; i++) {
temp[nowPosition] = points[i-1];
p1(nowPosition + 1, i, points);
}
}
}
}
Output:
no repetitions:
Output:
[1, 2, 3]
Output:
[1, 2, 4]
Output:
[1, 3, 4]
Output:
[2, 3, 4]
It is necessary to get rid of the recursive method call p1.
I tried to do so:
import java.util.*;
public class Main {
static int TOTAL_POINTS = 4, POINTS_ON_LINE = 3;
static int[] temp = new int[POINTS_ON_LINE];
public static void main(String[] args) {
int[] points = new int[]{1,2,3,4};
System.out.println("no repetitions:");
p1(points);
}
static void p1(int[] points) {
int sizeArray = points.length;
for(int i = sizeArray + 1; i < TOTAL_POINTS; i++, sizeArray = i) {
int nowPosition = 0;
if(nowPosition == POINTS_ON_LINE) {
System.out.println("Output: " + Arrays.toString(temp));
} else {
temp[nowPosition] = points[i-1];
nowPosition++;
}
}
}
}
Result - Output on console - empty.
It didn't work for me.
How to replace recursion?
Method # 1 (thanks for the suggested option - #deadshot)
package com.company;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Main {
static int TOTAL_POINTS = 4, POINTS_ON_LINE = 3;
static int[] temp = new int[POINTS_ON_LINE];
public static void main(String[] args) {
int[] points = new int[]{1, 2, 3, 4};
System.out.println("no repetitions:");
p1(points, POINTS_ON_LINE);
}
public static void p1(int[] arr, int base) {
int SIZE_ARRAY = arr.length;
List<Integer> indices = IntStream.range(0, base).boxed().collect(Collectors.toList());
for(Integer i : indices) {
System.out.println("- " + i);
}
if (base < SIZE_ARRAY) {
System.out.println("first");
System.out.println(indices.stream().map(idx -> arr[idx]).collect(Collectors.toList()));
boolean flag;
int i;
while (true) {
flag = false;
for (i = base - 1; i >= 0; i--)
if (indices.get(i) != i + SIZE_ARRAY - base) {
flag = true;
break;
}
if (!flag)
return;
indices.set(i, indices.get(i) + 1);
for (int j = i + 1; j < base; j++)
indices.set(j, indices.get(j - 1) + 1);
System.out.println(indices.stream().map(idx -> arr[idx]).collect(Collectors.toList()));
for(Integer x : indices) {
System.out.println("- " + x);
}
}
}
}
}
I have used python itertools.combinations code as reference to implement the method.
public class Main {
static int TOTAL_POINTS = 4, POINTS_ON_LINE = 3;
static int[] temp = new int[POINTS_ON_LINE];
public static void main(String[] args) {
int[] points = new int[]{1, 2, 3, 4};
System.out.println("no repetitions:");
p1(points, POINTS_ON_LINE);
}
public static void p1(int[] arr, int r) {
int n = arr.length, i;
int[] indices = new int[r];
for (i = 0; i < r; i++)
indices[i] = i;
if (r < n) {
for (int idx : indices)
temp[idx] = arr[idx];
System.out.println(Arrays.toString(temp));
boolean flag;
while (true) {
flag = false;
for (i = r - 1; i >= 0; i--)
if (indices[i] != i + n - r) {
flag = true;
break;
}
if (!flag)
return;
indices[i] += 1;
for (int j = i + 1; j < r; j++)
indices[j] = indices[j - 1] + 1;
for (i = 0; i < r; i++)
temp[i] = arr[indices[i]];
System.out.println(Arrays.toString(temp));
}
}
}
}

Leetcode : Remove Duplicates from Sorted Array

Why this code is not accepted by Leetcode compiler?
My program is running in netbeans. but leetcode compiler is not accepting it.
Here is my code:
import java.util.Arrays;
public class RemoveDuplicateFromArray {
public static int[] removeDuplicates(int[] nums) {
int temp, count = 0 ,l = 0;
temp = nums[0];
for(int i = 1; i < nums.length - (1 + l); i++ ) {
if(temp == nums[i]) {
count = count + 1;
for(int j = i; j < nums.length - count; j++){
nums[j] = nums[j+1];
}
i = i - 1;
} else {
temp = nums[i];
i = i ;
}
l = count;
}
nums = Arrays.copyOfRange(nums, 0, nums.length-count);
if(nums.length == 2){
if(nums[0] == nums[1]){
nums = Arrays.copyOfRange(nums, 0, nums.length-1);
}
}
return nums;
}
Here is my main mathod:
public static void main(String[] args) {
int[] nums = new int[] {1,1,1}; // showing error here.
System.err.println("nums lenght: " +nums.length);
int new_nums[] = removeDuplicates(nums);
for(int i : new_nums) {
System.err.print(i + " ");
}
}
}
The error is :
incompatible types: int[] cannot be converted to int.
I expect leetcode is having trouble with this line:
int new_nums[] = removeDuplicates(nums);
This isn't the typical way to define an integer array (this is the C style). Java does support the syntax, but it's a little arcane. See this answer for more detail.
Try this instead:
int[] new_nums = removeDuplicates(nums);
Just tried this on LeetCode, seems to work:
I would do it a bit like this myself:
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
int[] nums = new int[]{1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 5, 6, 7, 7, 7, 8, 9, 0, 0, 0, 0};
System.out.println("nums lenght: " + nums.length);
int[] new_nums = removeDuplicates(nums);
for (int i : new_nums) {
System.out.print(i + " ");
}
}
public static int[] removeDuplicates(int[] nums) {
List<Integer> found = new ArrayList();
for (int i = 1; i < nums.length; i++) {
if (!found.contains(nums[i])) {
found.add(nums[i]);
}
}
int[] ret = new int[found.size()];
for(int i = 0; i < found.size(); i++){
ret[i] = found.get(i);
}
return ret;
}
}
public class Solution {
public int removeDuplicates(int[] nums) {
int n = nums.length;
int i = 0;
int j = 1;
if (n <= 1) {
return n;
}
while (j <= n - 1) {
if (nums[i] != nums[j]) {
nums[i + 1] = nums[j];
i++;
}
j++;
}
return i + 1;
}
}
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import java.util.Arrays;
import org.junit.jupiter.api.Test;
class SolutionTest {
#Test
void removeDuplicates() {
int[] array = new int[] {1, 1, 2};
int end = new Solution().removeDuplicates(array);
assertThat(Arrays.toString(Arrays.copyOfRange(array, 0, end)), equalTo("[1, 2]"));
}
}

How to get unique integer pairs from an array of recurring pairs in Java?

The input values are 1,2,1,2,5,6,1,2,8,9,5,6,8,9.
The output should be in this form:
1,2 5,6 8,9
in a 2d string array. I tried this code but it's not working:
for(int u=0;u<=length_mfr/2;u=u+2)
{
for(int o=1;o<=length_mfr/2;o=o+2)
{
if(main_index[u][0]==main_index[u+2][o+2])
}
}
You're looking for unique pairs, not just unique numbers. Thus, the first step is to create a class to represent a pair.
public class Pair {
public final int first;
public final int second;
public Pair(int a, int b) {
first = a;
second = b;
}
public boolean equals(Object o) {
if (! (o instanceof Pair)) return false;
Pair p = (Pair)o;
return first == p.first && second == p.second;
}
public int hashCode() {
return first + second << 16;
}
public String toString() {
return "(" + first + "," + second + ")";
}
public String[] toStringArr() {
String[] s = new String[2];
s[0] = "" + first;
s[1] = "" + second;
return s;
}
}
From there you can turn your input in to pairs, do processing as necessary, and turn back into string array.
public static void main(String args[]){
int[] arr = { 1, 2, 1, 2, 5, 6, 1, 2, 8, 9, 5, 6, 8, 9 };
Set<Pair> set = new HashSet<>();
for(int i = 0; i < arr.length-1; i+=2) {
set.add(new Pair(arr[i], arr[i+1]));
}
String[][] arr2 = new String[set.size()][];
int i = 0;
for(Pair p : set) {
arr2[i] = p.toStringArr();
}
//Unique pairs now in string array arr2.
}
Given an int[] i with duplicates, you can create a TreeSet and add each element of the array i. TreeSet automatically removes duplicates and will contain only unique elements in ascending order.
public static void main(String args[])
{
int[] i = { 1, 2, 1, 2, 5, 6, 1, 2, 8, 9, 5, 6, 8, 9 };
Set<Integer> set = new TreeSet<>();
for (int e : i)
{
set.add(e);
}
// create an ArrayList to store all unique set values
// use Iterator to loop through ArrayList
ArrayList ar = new ArrayList<>(set);
Iterator it = ar.iterator();
// create index variable to loop through the str array
int index = 0;
// create String array str with the size of the set
String[] str = new String[set.size()];
while(it.hasNext() && index<set.size()){
str[index] = it.next().toString();
index++;
}
}
I hope this code will help you.
public static void main(String[] args) {
int[] num = { 1, 2, 1, 2, 5, 6, 1, 2, 8, 9, 5, 6, 8, 9 };
ArrayList<Integer> numDup = new ArrayList<Integer>();
numDup.add(num[0]);
for (int i = 0; i < num.length; i++) {
if (!numDup.contains(num[i])) {
numDup.add(num[i]);
}
}
for (Integer pVal : numDup) {
System.out.println(pVal);
}
}

Filtering out ints on an array

method takes in an array of ints and returns the new array of ints without even ints. Ive written something up but cannot get the print right in the main method....heres what I have
//filterAway method taking out evens from string
public static int[] filterArray(int[] x){
int [] arrayOne;
int size = 0;
for(int i=0; i<x.length; i++){
if(x[i] % 2 != 0){
size++;
}
}
arrayOne = new int [size];
int index =0;
for(int i=0; i<x.length; i++){
if(x[i] % 2 != 0){
arrayOne[index] = x[1];
index++;
}
}
return arrayOne;
}
//main
public static void main(String args[]){
int[] f = {1,2,3,4,5,6,7,8,9,10,11,12};
for (int i =0; i <f.length; i++){
System.out.print(f[i] + " ");
}
System.out.println(" ");
//here is where im struggling.
int [] fA= (filterAway); // say the string is 1-12....cannot get
// filtered array to print
for (int i =0; i <fA.length; i++){
System.out.print(arrayOne[i] + " ");
}``
System.out.println(" ");
}
Fixing the Display Problem
Try this revised main method, just replace YourClassName with your class name:
public static void main(String args[]) {
int[] f = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
for (int i = 0; i < f.length; i++) {
System.out.print(f[i] + " ");
}
System.out.println(" ");
// here is where im struggling.
int[] fA = YourClassName.filterArray(f);
// filtered array to print
for (int i = 0; i < fA.length; i++) {
System.out.print(fA[i] + " ");
}
System.out.println(" ");
}
However, you'll see you might end up getting something like 2, 2, 2, 2 there. You need to revisit your filterArray function.
Fixing the filterArray function
Since the title of your question is Filtering Out Ints in Java, here's the culprit, change 1 to i, that's why it gives out 2, 2, 2, 2. Also, you want even numbers, so you should look for 0 modulo, change your comparator to ==, instead of !=.
Here's what you should do with your requirements:
package com.sandbox;
public class Sandbox {
public static void main(String[] args) {
int[] all = new int[]{1, 2, 3, 4, 5, 6};
int[] filtered = odds(all);
for (int i : filtered) {
System.out.println(i);
}
}
private static int[] odds(int[] all) {
int sizeOfResult = 0;
for (int i : all) {
if (isOdd(i)) {
sizeOfResult++;
}
}
int[] result = new int[sizeOfResult];
int resultIndex = 0;
for (int i : all) {
if (isOdd(i)) {
result[resultIndex] = i;
resultIndex++;
}
}
return result;
}
private static boolean isOdd(int i) {
return i % 2 != 0;
}
}
Here's what I'd do if I were writing this on my own though: I'd use a List instead of an array, and I'd use CollectionUtils.filter. Here's a snippet of code that will do what you want:
package com.sandbox;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import java.util.ArrayList;
import java.util.List;
import static com.google.common.primitives.Ints.asList;
public class Sandbox {
public static void main(String[] args) {
List<Integer> result = new ArrayList<Integer>(asList(1, 2, 3, 4, 5, 6));
CollectionUtils.filter(result, new Predicate() {
#Override
public boolean evaluate(Object o) {
return isOdd((Integer) o);
}
});
for (Integer integer : result) {
System.out.println(integer);
}
}
private static boolean isOdd(int i) {
return i % 2 != 0;
}
}
You will need to pass your f[] as an argument to your filterAway() method.
public static void main(String args[]){
int[] f = {1,2,3,4,5,6,7,8,9,10,11,12};
for (int i =0; i <f.length; i++){
System.out.print(f[i] + " ");
}
System.out.println(" ");
int [] fA= filterArray(f);
for (int i =0; i <fA.length; i++){
System.out.print(fA[i] + " ");
}
System.out.println();
}

Calculating all of the subsets of a set of numbers

I want to find the subsets of a set of integers. It is the first step of "Sum of Subsets" algorithm with backtracking. I have written the following code, but it doesn't return the correct answer:
BTSum(0, nums);
///**************
ArrayList<Integer> list = new ArrayList<Integer>();
public static ArrayList<Integer> BTSum(int n, ArrayList<Integer> numbers) {
if (n == numbers.size()) {
for (Integer integer : list) {
System.out.print(integer+", ");
}
System.out.println("********************");
list.removeAll(list);
System.out.println();
} else {
for (int i = n; i < numbers.size(); i++) {
if (i == numbers.size() - 1) {
list.add(numbers.get(i));
BTSum(i + 1, numbers);
} else {
list.add(numbers.get(i));
for (int j = i+1; j < numbers.size(); j++)
BTSum(j, numbers);
}
}
}
return null;
}
For example, if I want to calculate the subsets of set = {1, 3, 5}
The result of my method is:
1, 3, 5, ********************
5, ********************
3, 5, ********************
5, ********************
3, 5, ********************
5, ********************
I want it to produce:
1, 3, 5
1, 5
3, 5
5
I think the problem is from the part
list.removeAll(list);
but I dont know how to correct it.
What you want is called a Powerset. Here is a simple implementation of it:
public static Set<Set<Integer>> powerSet(Set<Integer> originalSet) {
Set<Set<Integer>> sets = new HashSet<Set<Integer>>();
if (originalSet.isEmpty()) {
sets.add(new HashSet<Integer>());
return sets;
}
List<Integer> list = new ArrayList<Integer>(originalSet);
Integer head = list.get(0);
Set<Integer> rest = new HashSet<Integer>(list.subList(1, list.size()));
for (Set<Integer> set : powerSet(rest)) {
Set<Integer> newSet = new HashSet<Integer>();
newSet.add(head);
newSet.addAll(set);
sets.add(newSet);
sets.add(set);
}
return sets;
}
I will give you an example to explain how the algorithm works for the powerset of {1, 2, 3}:
Remove {1}, and execute powerset for {2, 3};
Remove {2}, and execute powerset for {3};
Remove {3}, and execute powerset for {};
Powerset of {} is {{}};
Powerset of {3} is 3 combined with {{}} = { {}, {3} };
Powerset of {2, 3} is {2} combined with { {}, {3} } = { {}, {3}, {2}, {2, 3} };
Powerset of {1, 2, 3} is {1} combined with { {}, {3}, {2}, {2, 3} } = { {}, {3}, {2}, {2, 3}, {1}, {3, 1}, {2, 1}, {2, 3, 1} }.
Just a primer how you could solve the problem:
Approach 1
Take the first element of your number list
generate all subsets from the remaining number list (i.e. the number list without the chosen one) => Recursion!
for every subset found in the previous step, add the subset itself and the subset joined with the element chosen in step 1 to the output.
Of course, you have to check the base case, i.e. if your number list is empty.
Approach 2
It is a well known fact that a set with n elements has 2^n subsets. Thus, you can count in binary from 0 to 2^n and interpret the binary number as the corresponding subset. Note that this approach requires a binary number with a sufficient amount of digits to represent the whole set.
It should be a not too big problem to convert one of the two approaches into code.
Your code is really confusing and there is no explanation.
You can do iteratively with a bitmask that determines which numbers are in the set. Each number from 0 to 2^n gives a unique subset in its binary representation, for example
for n = 3:
i = 5 -> 101 in binary, choose first and last elements
i = 7 -> 111 in binary, choose first 3 elements
Suppose there are n elements (n < 64, after all if n is larger than 64 you'll run that forever).
for(long i = 0; i < (1<<n); i++){
ArrayList<Integer> subset = new ArrayList<Integer>();
for(int j = 0; j < n; j++){
if((i>>j) & 1) == 1){ // bit j is on
subset.add(numbers.get(j));
}
}
// print subset
}
Considering a Noob Visitor (thanks to google) to this question - like me
Here is a recursive solution which works on simple principal :
Set = {a,b,c,d,e}
then we can break it to {a} + Subset of {b,c,d,e}
public class Powerset{
String str = "abcd"; //our string
public static void main(String []args){
Powerset ps = new Powerset();
for(int i = 0; i< ps.str.length();i++){ //traverse through all characters
ps.subs("",i);
}
}
void subs(String substr,int index)
{
String s = ""+str.charAt(index); //very important, create a variable on each stack
s = substr+s; //append the subset so far
System.out.println(s); //print
for(int i=index+1;i<str.length();i++)
subs(s,i); //call recursively
}
}
OUTPUT
a
ab
abc
abcd
abd
ac
acd
ad
b
bc
bcd
bd
c
cd
d
It is clear that, the total number of subsets of any given set is equal to 2^(number of elements in the set). If set
A = {1, 2, 3}
then subset of A is:
{ }, { 1 }, { 2 }, { 3 }, { 1, 2 }, { 1, 3 }, { 2, 3 }, { 1, 2, 3 }
If we look it is like binary numbers.
{ 000 }, { 001 }, { 010 }, { 011 }, { 100 }, { 101 }, { 110 }, { 111 }
If we take into account above:
static void subSet(char[] set) {
int c = set.length;
for (int i = 0; i < (1 << c); i++) {
System.out.print("{");
for (int j = 0; j < c; j++) {
if ((i & (1 << j)) > 0) {
System.out.print(set[j] + " ");
}
}
System.out.println("}");
}
}
public static void main(String[] args) {
char c[] = {'a', 'b', 'c'};
subSet(c);
}
private static void findSubsets(int array[])
{
int numOfSubsets = 1 << array.length;
for(int i = 0; i < numOfSubsets; i++)
{
int pos = array.length - 1;
int bitmask = i;
System.out.print("{");
while(bitmask > 0)
{
if((bitmask & 1) == 1)
System.out.print(array[pos]+",");
bitmask >>= 1;
pos--;
}
System.out.print("}");
}
}
Based on what I learnt today, here is the Java Solution
It is based on recursion
public class Powerset {
public static void main(String[] args) {
final List<List<String>> allSubsets = powerSet(Arrays.asList(1, 2, 3, 4), 0);
for (List<String> subsets : allSubsets) {
System.out.println(subsets);
}
}
private static List<List<String>> powerSet(final List<Integer> values,
int index) {
if (index == values.size()) {
return new ArrayList<>();
}
int val = values.get(index);
List<List<String>> subset = powerSet(values, index + 1);
List<List<String>> returnList = new ArrayList<>();
returnList.add(Arrays.asList(String.valueOf(val)));
returnList.addAll(subset);
for (final List<String> subsetValues : subset) {
for (final String subsetValue : subsetValues) {
returnList.add(Arrays.asList(val + "," + subsetValue));
}
}
return returnList;
}
}
Running it will give results as
[1]
[2]
[3]
[4]
[3,4]
[2,3]
[2,4]
[2,3,4]
[1,2]
[1,3]
[1,4]
[1,3,4]
[1,2,3]
[1,2,4]
[1,2,3,4]
public static void printSubsets(int[] arr) {
for (int start = 0; start < arr.length; start++) { // iterate through each element of the array
for (int i = 0; i < arr.length - start; i++) { // find number of subsets for the element
int[] tmp = new int[i + 1]; // calculate a temporal array size
for (int j = 0; j < tmp.length; j++) { // populate the array with corresponding elements
tmp[j] = arr[start + j];
}
System.out.println(Arrays.toString(tmp));
}
}
}
I was actually trying to solve this one and got the algorithm #phimuemue on the previous post .Here is what I implemented. Hope this works.
/**
*#Sherin Syriac
*
*/
import java.util.ArrayList;
import java.util.List;
public class SubSet {
ArrayList<List<Integer>> allSubset = new ArrayList<List<Integer>>();
/**
* #param args
*/
public static void main(String[] args) {
SubSet subSet = new SubSet();
ArrayList<Integer> set = new ArrayList<Integer>();
set.add(1);
set.add(2);
set.add(3);
set.add(4);
subSet.getSubSet(set, 0);
for (List<Integer> list : subSet.allSubset) {
System.out.print("{");
for (Integer element : list) {
System.out.print(element);
}
System.out.println("}");
}
}
public void getSubSet(ArrayList<Integer> set, int index) {
if (set.size() == index) {
ArrayList<Integer> temp = new ArrayList<Integer>();
allSubset.add(temp);
} else {
getSubSet(set, index + 1);
ArrayList<List<Integer>> tempAllSubsets = new ArrayList<List<Integer>>();
for (List subset : allSubset) {
ArrayList<Integer> newList = new ArrayList<Integer>();
newList.addAll(subset);
newList.add(set.get(index));
tempAllSubsets.add(newList);
}
allSubset.addAll(tempAllSubsets);
}
}
}
// subsets for the set of 5,9,8
import java.util.ArrayList;
import java.util.List;
public class Subset {
public static void main(String[] args) {
List<Integer> s = new ArrayList<Integer>();
s.add(9);
s.add(5);
s.add(8);
int setSize = s.size();
int finalValue = (int) (Math.pow(2, setSize));
String bValue = "";
for (int i = 0; i < finalValue; i++) {
bValue = Integer.toBinaryString(i);
int bValueSize = bValue.length();
for (int k = 0; k < (setSize - bValueSize); k++) {
bValue = "0" + bValue;
}
System.out.print("{ ");
for (int j = 0; j < setSize; j++) {
if (bValue.charAt(j) == '1') {
System.out.print((s.get(j)) + " ");
}
}
System.out.print("} ");
}
}
}
//Output : { } { 8 } { 5 } { 5 8 } { 9 } { 9 8 } { 9 5 } { 9 5 8 }
public static ArrayList<ArrayList<Integer>> powerSet(List<Integer> intList) {
ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
result.add(new ArrayList<Integer>());
for (int i : intList) {
ArrayList<ArrayList<Integer>> temp = new ArrayList<ArrayList<Integer>>();
for (ArrayList<Integer> innerList : result) {
innerList = new ArrayList<Integer>(innerList);
innerList.add(i);
temp.add(innerList);
}
result.addAll(temp);
}
return result;
}
If you're dealing with a large collection of elements, you may (though not likely) run into issues with stack overflow. I admit you're more likely to run out of memory before you overflow the stack, but I will put this non-recursive method here anyway.
public static final <T> Set<Set<T>> powerSet(final Iterable<T> original) {
Set<Set<T>> sets = new HashSet<>();
sets.add(new HashSet<>());
for (final T value : original) {
final Set<Set<T>> newSets = new HashSet<>(sets);
for (final Set<T> set : sets) {
final Set<T> newSet = new HashSet<>(set);
newSet.add(value);
newSets.add(newSet);
}
sets = newSets;
}
return sets;
}
Or if you'd rather deal with arrays:
#SuppressWarnings("unchecked")
public static final <T> T[][] powerSet(final T... original) {
T[][] sets = (T[][]) Array.newInstance(original.getClass(), 1);
sets[0] = Arrays.copyOf(original, 0);
for (final T value : original) {
final int oldLength = sets.length;
sets = Arrays.copyOf(sets, oldLength * 2);
for (int i = 0; i < oldLength; i++) {
final T[] oldArray = sets[i];
final T[] newArray = Arrays.copyOf(oldArray, oldArray.length + 1);
newArray[oldArray.length] = value;
sets[i + oldLength] = newArray;
}
}
return sets;
}
Simple Java recursive solution -
private static List<List<Integer>> allsubSet(List<Integer> integers, int start, int end) {
//Base case if there is only one element so there would be two subset
// empty list and that element
if(start == end) {
List<List<Integer>> result = new ArrayList<>();
List<Integer> emptyList = new ArrayList<>();
result.add(emptyList);
List<Integer> element = new ArrayList<>();
element.add(integers.get(start));
result.add(element );
return result;
}
//I know if by recursion we can expect that we'll get the n-1 correct result
List<List<Integer>> lists = allsubSet(integers, start, end-1);
//here i copy all the n-1 results and just added the nth element in expected results
List<List<Integer>> copyList = new ArrayList<>(lists);
for (List<Integer> list : lists) {
List<Integer> copy= new ArrayList<>(list);
copy.add(integers.get(end));
copyList.add(copy);
}
return copyList;
}
To avoid redundancy we can simply use Set in place of List
Get all subset using recursion (on similar lines for solving permutations from the book : Thinking recursively with Java)
public class ChapterSix {
public static void main(String[] args) {
new ChapterSix().listSubSets("", "123");
}
void listSubSets(String prefix, String s) {
System.out.println(prefix);
if("".equals(s)) {
return;
} else {
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
String rest = s.substring(i + 1);
listSubSets(prefix + ch, rest);
}
}
}
}
Output:
1
12
123
13
2
23
3
Here's some pseudocode. You can cut same recursive calls by storing the values for each call as you go and before recursive call checking if the call value is already present.
The following algorithm will have all the subsets excluding the empty set.
list * subsets(string s, list * v){
if(s.length() == 1){
list.add(s);
return v;
}
else
{
list * temp = subsets(s[1 to length-1], v);
int length = temp->size();
for(int i=0;i<length;i++){
temp.add(s[0]+temp[i]);
}
list.add(s[0]);
return temp;
}
}
Here's the logic to print all the subsets of a given set of numbers. This is also called powerset of a set. I have used a simple recursive approach to solve this using Java, but you can correspondingly code in other languages as well.
import java.util.Scanner;
public class PowerSubset {
public static void main(String[] args) {
// HardCoded Input
int arr[] = { 1, 2, 3 };//original array whose subset is to be found
int n=3; //size of array
// Dynamic Input
/*Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int arr[] = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = sc.nextInt();
}*/
int data[] = new int[arr.length]; // temporary array
printSubset(arr, data, n, 0, 0);
}
public static void printSubset(int arr[], int data[], int n, int dataIndex, int arrIndex) {
if (arrIndex == n) { //comparing with n since now you are at the leaf node
System.out.print("[");//watch pictorial chart in the below video link
for (int j = 0; j < n; j++) {
System.out.print(data[j] == 0 ? "" : data[j]);
}
System.out.print("]");
System.out.println();
return;
}
data[dataIndex] = arr[arrIndex];
printSubset(arr, data, n, dataIndex + 1, arrIndex + 1);//recursive call 1
data[dataIndex] = 0;
printSubset(arr, data, n, dataIndex, arrIndex + 1);//recursive call 2
}
}
Output of the above code:
[123]
[12]
[13]
[1]
[23]
[2]
[3]
[]

Categories

Resources