子集生成(递归+set集合的使用)

子集生成

  1. 题目:
    请编写一个方法,返回某集合的所有非空子集。
    给定一个int数组A和数组的大小int n,请返回A的所有非空子集。
    保证A的元素个数小于等于20,且元素互异。
    各子集内部从大到小排序,子集之间字典逆序排序

  2. 知识点:

Set<Set<Character>> res = new HashSet<>();
    res.add(new HashSet<>());
    Set r=new HashSet<>();
    r.add('s');
    r.add('d');
    res.add(r);
    System.out.print(res);	//[[], [s, d]]

Set<Set> res = new HashSet<>();——类似于二维数组,里面的每个元素都是一个set集合
Set r=new HashSet<>();——里面的元素是就是一些基本数据类型或者类的实例化对象。

char[] A = {'a', 'b', 'c'};
//字符数组只能打单引号!

字符数组只能打单引号!

  1. 代码:
import java.util.Scanner;
import java.util.HashSet;
import java.util.Set;

import java.util.*;

/**
 请编写一个方法,返回某集合的所有非空子集。

 给定一个int数组A和数组的大小int n,请返回A的所有非空子集。
 保证A的元素个数小于等于20,且元素互异。

 各子集内部从大到小排序,子集之间字典逆序排序
 */
public class Main {

  public static void main(String[] args) {
    char[] A = {'a', 'b', 'c'};
    Main obj = new Main();

    Set<Set<Character>> subsets3 = obj.getSubsets3(A, A.length);
    System.out.println(subsets3);

    Set<Set<Character>> subsets2 = obj.getSubsets2(A, A.length);
    System.out.println(subsets2);
    Set<Set<Character>> a1=new HashSet<>();//集合的集合,元素是集合,只能向里面添加set集合 
    Set<Set<Character>> a2=new HashSet<>();
    Set<Set<Character>> a3=new HashSet<>();
    Set<Set<Character>> res = new HashSet<>();
    res.add(new HashSet<>());
    Set r=new HashSet<>();
    r.add('s');
    r.add('d');
    res.add(r);
    System.out.print(res);
  }

  /**
   * 二进制法,迭代法,或者逐步生成法
   * @param a
   * @param n
   * @return
   */
  

  /*逐步生成迭代大法*/
  public Set<Set<Character>> getSubsets2(char[] a, int n) {
    Set<Set<Character>> res = new HashSet<>();
    res.add(new HashSet<>());//初始化为空集
    //从第一个元素开始处理
    for (int i = 0; i < n; i++) {
      Set<Set<Character>> res_new = new HashSet<>();//新建一个大集合
      res_new.addAll(res);//把原来集合中的每个子集都加入到新集合中
      //遍历之前的集合,全部克隆一遍
      for (Set e : res) {
        Set clone = (Set) ((HashSet) e).clone();
        clone.add(a[i]);//把当前元素加进去
        res_new.add(clone);//把克隆的子集加到大集合中
      }
      res = res_new;
    }
    return res;
  }

  /**
   * 增量构造法
   * @param a
   * @param n
   * @return
   */
  public Set<Set<Character>> getSubsets3(char[] a, int n) {
    // Arrays.sort(A);
    return getSubsets3Core(a, n, n - 1);

  }

  /**
   * 递归增量构造法
   * @param a
   * @param n
   * @param cur
   * @return
   */
  private Set<Set<Character>> getSubsets3Core(char[] a, int n, int cur) {
    Set<Set<Character>> newSet = new HashSet<>();
    if (cur == 0) {//处理第一个元素
      Set<Character> nil = new HashSet<>();//空集
      Set<Character> first = new HashSet<>();//包含第一个元素的集合
      first.add(a[0]);
      newSet.add(nil);
      newSet.add(first);
      return newSet;
    }

    Set<Set<Character>> oldSet = getSubsets3Core(a, n, cur - 1);
    for (Set<Character> set : oldSet) {
      //对于每个子集,cur这个元素可以加进去,也可以不加进去
      newSet.add(set);//保留原样
      Set<Character> clone = (Set<Character>) ((HashSet) set).clone();
      clone.add(a[cur]);//添加当前元素
      newSet.add(clone);
    }
    return newSet;
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值