Java 如何从arrayList对象生成所有可能的幂集(或子集)?
假设我有以下课程:Java 如何从arrayList对象生成所有可能的幂集(或子集)?,java,collections,hashmap,subset,powerset,Java,Collections,Hashmap,Subset,Powerset,假设我有以下课程: class A { String name; Double value; } 以及上述类对象的列表,这些对象可能具有: [{f 2.1}, {c 1.1}, {a 0.3}... and so on] [{n 0.5}, {f 1.9}, {x 0.1}, {a 1.9}, {b 1.1}... and so on] ... and so on 我只想做以下几件事: 1. Building power subsets from the in
class A {
String name;
Double value;
}
以及上述类对象的列表,这些对象可能具有:
[{f 2.1}, {c 1.1}, {a 0.3}... and so on]
[{n 0.5}, {f 1.9}, {x 0.1}, {a 1.9}, {b 1.1}... and so on]
... and so on
我只想做以下几件事:
1. Building power subsets from the internal list items(N.B: skip the single subsets).
2. Push the subset in another List as an object of the above class A like this:
a. if f,c is a subset of 1st element then f,c would be the name property of class A
and the value property will be the minimum of f and c from the list.
Like: {f,c 1.1} [ where f,c is a subset and min of 2.1(value of f)
and 1.1(value of c) is 1.1]
so, from the above list if I take 1st element the subsets and their values
in the pushing list would be like this(after skipping the single subsets):
[{f,c 1.1}, {c,a 0.3}, {f,a 0.3}, {f,c,a 0.3}]
and for the 2nd element this would be:
[{n,f 0.5}, {f,x 0.1}, {x,a 0.1}, {a,b 1.1}, {n,x 0.1}, {n,a 0.5}, {n,b 0.5},
{f,a 1.9}, {f,b 1.1}, {x,b 0.1}, {n,f,x 0.1}, {n,x,a 0.1},
{n,a,b 0.5}, {f,x,a 0.1}, {f,x,b 0.1}, {x,a,b 0.1}, {n,f,x,a 0.1},
{n,f,x,b 0.1}, {n,f,a,b 0.5}, {n,x,a,b 0.1}, {f,x,a,b 0.1},
{n,f,x,a,b 0.1}]
有人能告诉我如何用Java实现这一点吗(如果可能的话,请提供一些示例代码)
谢谢 我假设输出列表中每个元素的子集顺序是不相关的 对于任何重要大小的输入,您的输出都会非常大,因此不要试图将其保存在内存中。最好将PowerList实现为自己的集合。下面的草稿只适用于长度为31或更少的输入,不过滤单例或空列表
public class PowerList extends AbstractList< A > {
private final List< A > laUnderlying;
public PowerList( List< A > laUnderlying ) {
this.laUnderlying = laUnderlying;
}
@Override
public A get( int index ) {
StringBuilder sbLabel;
A aOut = new A();
aOut.value = Double.MAX_VALUE;
int iUnderIndex = 0;
while ( 0 < index ) {
while ( 0 == ( index & 1 ) ) {
++iUnderIndex;
index = index >> 1;
}
A aComponent = laUnderlying.get( index );
sbLabel.append( ',' ).append( aComponent.name );
if ( aComponent.value < aOut.value )
aOut.value = aComponent.value;
}
if ( !sbLabel.isEmpty() )
aOut.name = sbLabel.substring( 1 );
return aOut;
}
public int size() {
return 1 << laUnderlying.size();
}
}
公共类PowerList扩展了AbstractList{
私人最终名单清洗;
公共权力列表(列表清洗){
this.launderlaying=洗衣服;
}
@凌驾
公共A get(int索引){
StringBuilder标签;
A aOut=新的A();
aOut.value=Double.MAX_值;
int iUnderIndex=0;
而(0<指数){
而(0==(索引和1)){
++指数;
指数=指数>>1;
}
A组件=清洗。获取(索引);
sbLabel.append(',').append(aComponent.name);
如果(a组件值输出;
对于(列表laEach:llaInput)
添加(新的PowerList(laEach));
注意:电源集很快就会变大,因此即使很小的输入也会耗尽内存。但是,如果您有内存,则没有其他限制
// As stated.
class A {
String name;
double value;
A(String name, double value) {
this.name = name;
this.value = value;
}
}
// Powerset set.
class ASet {
final ArrayList<String> names = new ArrayList<String>();
double value = Double.MAX_VALUE;
void adjoin(A a) {
names.add(a.name);
value = Math.min(value, a.value);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append('{');
for (String name : names) {
sb.append(name);
sb.append(',');
}
sb.append(value);
sb.append('}');
return sb.toString();
}
}
// Make power sets.
class PowerSetFactory {
// Stack for intermediate results.
final ArrayDeque<A> stack = new ArrayDeque<A>();
// Source data.
ArrayList<A> src;
// Powerset under construction
ArrayList<ASet> dst;
// Recursive powerset calculator
private void recur(int i) {
if (i >= src.size()) {
// Stack is complete. If more than 1 element,
// add its contents to the result.
if (stack.size() > 1) {
ASet set = new ASet();
for (A a : stack) set.adjoin(a);
dst.add(set);
}
}
else {
// Otherwise recur both without and with this element
// added to the stack. Clean up the stack before return.
recur(i + 1);
stack.offerLast(src.get(i));
recur(i + 1);
stack.pollLast();
}
}
// Get a powerset for the givens source data.
ArrayList<ASet> getPowerSet(ArrayList<A> src) {
this.src = src;
this.dst = new ArrayList<ASet>();
recur(0);
return dst;
}
public void test() {
ArrayList<A> data = new ArrayList<A>();
data.add(new A("f", 2.1));
data.add(new A("c", 1.1));
data.add(new A("a", 0.3));
for (ASet set : getPowerSet(data)) {
System.out.print(set);
}
System.out.println();
data.clear();
data.add(new A("n", 0.5));
data.add(new A("f", 1.9));
data.add(new A("x", 0.1));
data.add(new A("a", 1.9));
data.add(new A("b", 1.1));
for (ASet set : getPowerSet(data)) {
System.out.print(set);
}
System.out.println();
}
}
//如上所述。
甲级{
字符串名;
双重价值;
A(字符串名称,双值){
this.name=名称;
这个值=值;
}
}
//动力装置组。
ASet类{
最终ArrayList名称=新ArrayList();
双倍值=双倍最大值;
虚空邻接(A){
名称。添加(a.名称);
value=Math.min(value,a.value);
}
@凌驾
公共字符串toString(){
StringBuilder sb=新的StringBuilder();
某人附加('{');
for(字符串名称:名称){
某人(姓名);
某人附加(“,”);
}
附加(价值);
某人附加('}');
使某人返回字符串();
}
}
//制造发电机组。
类动力装置厂{
//用于中间结果的堆栈。
最终ArrayQue堆栈=新ArrayQue();
//源数据。
arraylistsrc;
//在建发电机组
阵列列表dst;
//递归功率集计算器
私人无效重现(int i){
如果(i>=src.size()){
//堆栈已完成。如果超过1个元素,
//将其内容添加到结果中。
if(stack.size()>1){
ASet集合=新ASet();
对于(A:stack)集合。邻接(A);
dst.add(set);
}
}
否则{
//否则,不使用此元素和使用此元素都会重复出现
//已添加到堆栈。返回前请清理堆栈。
复发(i+1);
stack.offerLast(src.get(i));
复发(i+1);
stack.pollLast();
}
}
//获取givens源数据的电源集。
ArrayList getPowerSet(ArrayList src){
this.src=src;
this.dst=新的ArrayList();
复发(0);
返回dst;
}
公开无效测试(){
ArrayList数据=新的ArrayList();
增加(新的A(“f”,2.1));
增加(新的A(“c”,1.1));
数据。添加(新A(“A”,0.3));
用于(ASet集合:getPowerSet(数据)){
系统输出打印(套);
}
System.out.println();
data.clear();
数据。添加(新的A(“n”,0.5));
增加(新的A(“f”,1.9));
添加(新的A(“x”,0.1));
增加(新的A(“A”,1.9));
增加(新的A(“b”,1.1));
用于(ASet集合:getPowerSet(数据)){
系统输出打印(套);
}
System.out.println();
}
}
我认为您有一个列表这一事实对这个问题无关紧要,因为我认为外部列表的元素与输出之间没有交互作用。您应该简化为如何为一个输入元素获取一个输出元素的问题。@Ju断:对不起,我犯了一个问题。现在编辑。
// As stated.
class A {
String name;
double value;
A(String name, double value) {
this.name = name;
this.value = value;
}
}
// Powerset set.
class ASet {
final ArrayList<String> names = new ArrayList<String>();
double value = Double.MAX_VALUE;
void adjoin(A a) {
names.add(a.name);
value = Math.min(value, a.value);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append('{');
for (String name : names) {
sb.append(name);
sb.append(',');
}
sb.append(value);
sb.append('}');
return sb.toString();
}
}
// Make power sets.
class PowerSetFactory {
// Stack for intermediate results.
final ArrayDeque<A> stack = new ArrayDeque<A>();
// Source data.
ArrayList<A> src;
// Powerset under construction
ArrayList<ASet> dst;
// Recursive powerset calculator
private void recur(int i) {
if (i >= src.size()) {
// Stack is complete. If more than 1 element,
// add its contents to the result.
if (stack.size() > 1) {
ASet set = new ASet();
for (A a : stack) set.adjoin(a);
dst.add(set);
}
}
else {
// Otherwise recur both without and with this element
// added to the stack. Clean up the stack before return.
recur(i + 1);
stack.offerLast(src.get(i));
recur(i + 1);
stack.pollLast();
}
}
// Get a powerset for the givens source data.
ArrayList<ASet> getPowerSet(ArrayList<A> src) {
this.src = src;
this.dst = new ArrayList<ASet>();
recur(0);
return dst;
}
public void test() {
ArrayList<A> data = new ArrayList<A>();
data.add(new A("f", 2.1));
data.add(new A("c", 1.1));
data.add(new A("a", 0.3));
for (ASet set : getPowerSet(data)) {
System.out.print(set);
}
System.out.println();
data.clear();
data.add(new A("n", 0.5));
data.add(new A("f", 1.9));
data.add(new A("x", 0.1));
data.add(new A("a", 1.9));
data.add(new A("b", 1.1));
for (ASet set : getPowerSet(data)) {
System.out.print(set);
}
System.out.println();
}
}