Java 打印列表的所有可能子集
我有一个元素列表(1、2、3),我需要获取该列表的超集(powerset)(没有重复的元素)。所以基本上我需要创建一个列表,如下所示:Java 打印列表的所有可能子集,java,algorithm,powerset,superset,Java,Algorithm,Powerset,Superset,我有一个元素列表(1、2、3),我需要获取该列表的超集(powerset)(没有重复的元素)。所以基本上我需要创建一个列表,如下所示: {1} {2} {3} {1, 2} {1, 3} {2, 3} {1, 2, 3} 实现这一点的最佳方式(简单性>效率在这种情况下,列表不会很大)是什么?最好使用Java,但任何语言的解决方案都很有用。使用位掩码: int allMasks = (1 << N); for (int i = 1; i < allMasks; i++) {
{1}
{2}
{3}
{1, 2}
{1, 3}
{2, 3}
{1, 2, 3}
实现这一点的最佳方式(简单性>效率在这种情况下,列表不会很大)是什么?最好使用Java,但任何语言的解决方案都很有用。使用位掩码:
int allMasks = (1 << N);
for (int i = 1; i < allMasks; i++)
{
for (int j = 0; j < N; j++)
if ((i & (1 << j)) > 0) //The j-th element is used
System.out.print((j + 1) + " ");
System.out.println();
}
1 = 001 = {1}
2 = 010 = {2}
3 = 011 = {1, 2}
4 = 100 = {3}
5 = 101 = {1, 3}
6 = 110 = {2, 3}
7 = 111 = {1, 2, 3}
您知道在二进制中,第一位是最右边的。import java.io.*;
import java.io.*;
import java.util.*;
class subsets
{
static String list[];
public static void process(int n)
{
int i,j,k;
String s="";
displaySubset(s);
for(i=0;i<n;i++)
{
for(j=0;j<n-i;j++)
{
k=j+i;
for(int m=j;m<=k;m++)
{
s=s+m;
}
displaySubset(s);
s="";
}
}
}
public static void displaySubset(String s)
{
String set="";
for(int i=0;i<s.length();i++)
{
String m=""+s.charAt(i);
int num=Integer.parseInt(m);
if(i==s.length()-1)
set=set+list[num];
else
set=set+list[num]+",";
}
set="{"+set+"}";
System.out.println(set);
}
public static void main()
{
Scanner sc=new Scanner(System.in);
System.out.println("Input ur list");
String slist=sc.nextLine();
int len=slist.length();
slist=slist.substring(1,len-1);
StringTokenizer st=new StringTokenizer(slist,",");
int n=st.countTokens();
list=new String[n];
for(int i=0;i<n;i++)
{
list[i]=st.nextToken();
}
process(n);
}
}
导入java.util.*;
类子集
{
静态字符串列表[];
公共静态无效进程(int n)
{
int i,j,k;
字符串s=“”;
显示子集;
对于(i=0;i基于Petar Minchev解决方案的java解决方案-
public static List<List<Integer>> getAllSubsets(List<Integer> input) {
int allMasks = 1 << input.size();
List<List<Integer>> output = new ArrayList<List<Integer>>();
for(int i=0;i<allMasks;i++) {
List<Integer> sub = new ArrayList<Integer>();
for(int j=0;j<input.size();j++) {
if((i & (1 << j)) > 0) {
sub.add(input.get(j));
}
}
output.add(sub);
}
return output;
}
公共静态列表GetAllSubset(列表输入){
int-allMasks=1我注意到答案集中在字符串列表上。
因此,我决定分享更一般的答案。
希望这会很有帮助。
(Soultion基于我找到的另一个解决方案,我将其组合到一个通用算法中。)
/**
*metod返回给定列表的所有子列表
*该方法假定所有对象都不同
*无论列表的类型如何(泛型)
*@param list返回所有子列表的列表
*@param
*@返回可从列表对象生成的不同子列表的列表
*/
公共静态ListGetAllSubList(Listlist)
{
列表子列表;
Listres=newarraylist();
列表索引=所有子列表索引(List.size());
对于(列表子索引:索引)
{
subList=新的ArrayList();
for(int索引:子索引)
subList.add(list.get(index));
res.add(子列表);
}
返回res;
}
/**
*方法返回整数列表的列表,这些整数表示N大小列表中所有子列表的索引
*@param n列表的大小
*@返回子列表的索引整数列表
*/
公共静态列表所有子列表索引(int n){
List res=new ArrayList();
int allMasks=(1这是一个简单的函数,可用于创建由给定数组或列表的所有可能子集的数字生成的所有可能数字的列表
void SubsetNumbers(int[] arr){
int len=arr.length;
List<Integer> list=new ArrayList<Integer>();
List<Integer> list1=new ArrayList<Integer>();
for(int n:arr){
if(list.size()!=0){
for(int a:list){
list1.add(a*10+n);
}
list1.add(n);
list.addAll(list1);
list1.clear();
}else{
list.add(n);
}
}
System.out.println(list.toString());
}
void子编号(int[]arr){
int len=arr.length;
列表=新的ArrayList();
List list1=新的ArrayList();
用于(整数n:arr){
如果(list.size()!=0){
用于(INTA:列表){
列表1.添加(a*10+n);
}
列表1.添加(n);
list.addAll(列表1);
清单1.clear();
}否则{
列表。添加(n);
}
}
System.out.println(list.toString());
}
在给定的解决方案中,我们迭代每个索引,包括当前和所有其他元素
class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> ans = new ArrayList<>();
if(nums == null || nums.length ==0){
return ans;
}
Arrays.sort(nums);
List<Integer> subset = new ArrayList<>();
allSubset(nums, ans , subset , 0);
return ans;
}
private void allSubset(int[] nums,List<List<Integer>> ans ,List<Integer> subset , int idx){
ans.add(new ArrayList<>(subset));
for(int i = idx; i < nums.length; i++){
subset.add(nums[i]);
allSubset(nums, ans , subset , i+1);
subset.remove(subset.size() - 1);
}
}
}
类解决方案{
公共列表子集(int[]nums){
List ans=新的ArrayList();
if(nums==null | | nums.length==0){
返回ans;
}
数组。排序(nums);
列表子集=新的ArrayList();
allSubset(nums,ans,subset,0);
返回ans;
}
私有void allSubset(int[]nums,List ans,List subset,int idx){
ans.add(新数组列表(子集));
对于(int i=idx;i
Peter Minchev的解决方案修改为通过BigInteger处理较大的列表
public static List<List<Integer>> getAllSubsets(List<Integer> input) {
BigInteger allMasks = BigInteger.ONE.shiftLeft(input.size());
List<List<Integer>> output = new ArrayList<>();
for(BigInteger i=BigInteger.ZERO;allMasks.subtract(i).compareTo(BigInteger.ZERO)>0; i=i.add(BigInteger.ONE)) {
List<Integer> subList = new ArrayList<Integer>();
for(int j=0;j<input.size();j++) {
if(i.and(BigInteger.valueOf(1<<j)).compareTo(BigInteger.ZERO) > 0) {
subList.add(input.get(j));
}
}
System.out.println(subList);
output.add(subList);
}
return output;
}
公共静态列表GetAllSubset(列表输入){
biginger allMasks=biginger.ONE.shiftLeft(input.size());
列表输出=新的ArrayList();
对于(biginger i=biginger.ZERO;allMasks.subtract(i).compareTo(biginger.ZERO)>0;i=i.add(biginger.ONE)){
列表子列表=新的ArrayList();
对于(int j=0;jj)您需要该列表的所有子集。我建议使用递归。但是,如果您处理的元素超过30-40个,您将无法处理您拥有的大量(超过1TB的数据)。这是用来做什么的?您正在寻找的此数据结构称为Powerset(不同之处在于它还包含一个空集).这已经讨论过了。谢谢Zenzen为我指出了正确的方向…我发现了。这些不是,这些是子集。这很有趣…你显然比我聪明得多-给我一些时间让我思考一下这个问题…N是原始列表中的元素数吗?我映射了列表中的对象吗对于整数?@Steve-是的,N
是元素的数量-在你上面的例子中N=3
。想想二进制-如果不使用元素,位是0,如果使用元素,位是1。例如二进制中的5=101。这意味着使用了1
和3
。={1,3}
我认为这对中等大小或以上的列表不起作用,allMasks整数会起作用overflow@mancini0-大约31位(2^31)后会溢出,这是整数的最大值,它已经是一个20亿的庞大数字。如果需要打印或迭代20亿个数字,则会出现错误:)@PetarMinchev我同意:),我唯一的使用案例是一个实践面试问题,其中我需要返回大小为50的所有排列(2^50排列,10^15可能)受制于谓词。为此,我修改了你的解决方案,使用大整数。修改后的解决方案将在40年左右的时间内得出正确的答案,但至少面试官不能说这是一个错误的解决方案。顺便说一句,你的解很漂亮。程序很简单。首先,我们尝试得到1-n d的所有可能组合igit编号,直到每个列表的最后一位为1,2,3,…。n位编号为n。然后使用每个组合提取其每个字符(即编号),并显示存储在由该字符(编号)表示的单元格索引中的子集的元素。最好添加cod的说明
public static List<List<Integer>> getAllSubsets(List<Integer> input) {
BigInteger allMasks = BigInteger.ONE.shiftLeft(input.size());
List<List<Integer>> output = new ArrayList<>();
for(BigInteger i=BigInteger.ZERO;allMasks.subtract(i).compareTo(BigInteger.ZERO)>0; i=i.add(BigInteger.ONE)) {
List<Integer> subList = new ArrayList<Integer>();
for(int j=0;j<input.size();j++) {
if(i.and(BigInteger.valueOf(1<<j)).compareTo(BigInteger.ZERO) > 0) {
subList.add(input.get(j));
}
}
System.out.println(subList);
output.add(subList);
}
return output;
}