采用
位掩码实现打印给定数组所有的非空子集。
分析:
首先来看一个例子,如果给定一个正整数N,如何输出由1到N组成的数组所有的非空子集呢?
如N=3, 那么1到3组成的数组为{1,2,3},数组长度为3,那么二进制表示有
1<<3 = 8种。
0 = 000 = {} 空集
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}
遍历所有的二进制表达式,考虑其中1的位置,并打印相应的值,就能得到我们想要的结果。
代码如下:
/**
*
* 给定一个正整数N,输出由1到N组成的数组所有的非空子集。
* 如N=3, 那么1到3组成的数组为{1,2,3}
*
* 所有二进制的情况
*
* 0 = 000 = {} 空集
* 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}
*
*/
public void printAllSubsets(int N) {
if (N <=0) {
throw new IllegalArgumentException("参数应该是一个正整数。");
}
int allMasks = 1 << N;
//如考虑空集 ,那么i的初始值为0
for (int i = 1; i < allMasks; i++) {
for (int j = 0; j < N; j++)
if ((i & (1 << j)) > 0)
System.out.print((j + 1) + " ");
System.out.println();
}
}
依据上述例子的实现方式,下面的方法实现打印一个字符串数组所拥有的所有非空子集。
/**
* 打印一个数组所有的非空子集
*/
public void printAllSubsets(String[] array) {
if (null == array || 0 == array.length) {
throw new IllegalArgumentException("数组不能为Null,至少有一个元素");
}
// 数组长度
int len = array.length;
// 根据数据的长度,得出所有二进制的个数
// 如len =2;
// 0 = 00 = {}
// 1 = 01 = {1}
// 2 = 10 = {2}
// 3 = 11 = {1, 2}
int allMasks = 1 << len;
// 遍历所有的二进制表示方式
for (int i = 1; i < allMasks; i++) {
for (int j = 0; j < len; j++)
if ((i & (1 << j)) > 0)
System.out.print(array[j] + " ");
System.out.println();
}
}
具体的代码和简单的测试如下:
public class PrintAllNonEmptySubsets {
/**
*
* 给定一个正整数N,输出由1到N组成的数组所有的非空子集。
* 如N=3, 那么1到3组成的数组为{1,2,3}
*
* 所有二进制的情况
*
* 0 = 000 = {} 空集
* 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}
*
*/
public void printAllSubsets(int N) {
if (N <=0) {
throw new IllegalArgumentException("参数应该是一个正整数。");
}
int allMasks = 1 << N;
//如考虑空集 ,那么i的初始值为0
for (int i = 1; i < allMasks; i++) {
for (int j = 0; j < N; j++)
if ((i & (1 << j)) > 0)
System.out.print((j + 1) + " ");
System.out.println();
}
}
/**
* 打印一个数组所有的非空子集
*/
public void printAllSubsets(String[] array) {
if (null == array || 0 == array.length) {
throw new IllegalArgumentException("数组不能为Null,至少有一个元素");
}
// 数组长度
int len = array.length;
// 根据数据的长度,得出所有二进制的个数
// 如len =2;
// 0 = 00 = {}
// 1 = 01 = {1}
// 2 = 10 = {2}
// 3 = 11 = {1, 2}
int allMasks = 1 << len;
// 遍历所有的二进制表示方式
for (int i = 1; i < allMasks; i++) {
for (int j = 0; j < len; j++)
if ((i & (1 << j)) > 0)
System.out.print(array[j] + " ");
System.out.println();
}
}
public static void main(String[] args) {
PrintAllNonEmptySubsets exam = new PrintAllNonEmptySubsets();
exam.printAllSubsets(new String[] { "a", "b", "c" });
exam.printAllSubsets(3);
}
}
输出结果:
a
b
a b
c
a c
b c
a b c
1
2
1 2
3
1 3
2 3
1 2 3
分享到:
相关推荐
N个元素的集合{1,2,3...,n}可以划分为若干个非空子集。例如,当n=2时,集合{1,2,3}可以划分为2个不同的非空子集如下:{{1},{2}},{{1,2}}。编程任务:给定正整数N,计算出N个元素的集合{1,2,3,.....n}可以划分为...
具体来说,对于一个包含`n`个元素的集合`{1,2,...,n}`,我们需要计算其能够划分为多少个不同的非空子集的方式。例如,当`n = 4`时,集合`{1,2,3,4}`可以被划分为15种不同的非空子集组合。 #### 二、问题解析 **...
题目要求我们判断给定的两个长度相同的整数数组`target`和`arr`是否可以通过翻转`arr`中的非空子数组使其变得与`target`相同。 首先,我们需要理解“翻转子数组”的概念。在数组中,翻转一个子数组意味着将该子数组...
求子集问题--一个ACM程序竞赛题 本文将详细讲解求子集问题,这是一个ACM程序竞赛题。该问题的描述是:已知N个大于0的整数构成一个集合,即{1,2,3,……,N},求其所有的非空且元素不相邻的子集,计算所有子集的...
在JavaScript编程语言中,获取一个字符串中只包含一种字符的最长非空子字符串的长度是一项常见的字符串处理任务。这个问题可以通过遍历字符串并检测连续字符来解决。以下是一种实现方法: ```javascript /** * ...
假设G是一个群,那么由G的所有非空子集构成的集合A可以形成一个新的群结构。在这个群A中,群的单位元就是G的单位元,而元素的乘法则由集合的乘积来定义。如果N是G的一个正规子群,则商群G/N可以视为是由G的非空子集...
一个字符串的非空子串是指字符串中长度至少为 1 的连续的一段字符组成 的串。例如,字符串aaab 有非空子串a, b, aa, ab, aaa, aab, aaab,一共 7 个。 注意在计算时,只算本质不同的串的个数。 请问,字符串...
给定一个整数数组A,我们要检查是否可以找到三个连续的非空子数组,使得这三个子数组的和相等。例如,在示例1中,数组`[0, 2, 1, -6, 6, -7, 9, 1, 2, 0, 1]`可以被划分为`[0, 2, 1]`, `[2, -6, 6, -7, 9, 1]`, 和`...
集合划分:包含n个元素的集合划分为正好k个非空子集的方法的数目
C/C++ 求一个集合的子集,代码易懂,好用,谢谢下载
2. **数组拆分II (Split Array with Equal Sum)**:在这个问题中,目标是将数组拆分为若干个非空子数组,使得每个子数组的和相等。这需要对数组进行深思熟虑的遍历,并可能涉及哈希表来存储子数组的和及其出现的次数...
3. **初始化第一个非空子集**:将`set[0]`设置为1,表示集合中的第一个元素。 4. **循环生成子集**: - 每次循环都打印当前子集。 - 如果当前子集还有空间添加新的元素(`set[position] ),则在`set`数组末尾增加...
在这个例子中,尽管数组`$arr`包含了三个空子数组,但`implode()`并不会把它们转换为一个空字符串,所以`$str`将包含逗号分隔的三个空元素,导致判断结果为"非空",从而产生错误的结论。 在实际开发中,针对多维...
在计算机科学领域,子数组最大和问题(Maximal Contiguous Subsequent Sum Problem)是一个经典的问题,旨在从一个整数数组中找出具有最大和的连续子数组。该问题在算法设计和分析中具有重要意义,广泛应用于数据...
数组的特点是通过一个下标(或索引)来访问其元素,这个下标通常是整数,从0开始。数组的优点是访问速度快,因为它的元素在内存中是连续存储的,可以通过简单的算术运算直接计算出元素的地址。然而,数组的大小在...
D3.js通常期望的数据格式是一个扁平的数组,其中包含所有节点,以及表示它们之间关系的父节点字段。例如: ```json [ {"data": "父节点", "children": [{"data": "左子节点"}, {"data": "右子节点"}]}, {"data": ...
给定一个集合,我们需要将其划分为m个非空子集。这个问题可以通过动态规划来解决。以三个元素为例,我们可以计算出不同划分的数量。当添加第四个元素时,我们可以选择将其加入现有的任何一个子集,或者创建一个新的...
Apriori算法的核心思想是基于“频繁项集的任何非空子集也必须是频繁的”这一性质,采用迭代的方式逐层生成频繁项集。首先,通过扫描数据库,计算每个项的支持度,筛选出频繁1项集。接着,利用频繁1项集生成候选频繁2...
求一个集合的所有子集的C++实现
10. 第10篇:子集分组(2023-09-13):使用go语言,给定一个整数数组nums和一个正整数k,找到是否有可能把这个数组分成k个非空子集,其总和都相等。 11. 第11篇:团队选择(2023-09-10):使用go语言,作为项目经理...