Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何从arrayList对象生成所有可能的幂集(或子集)?_Java_Collections_Hashmap_Subset_Powerset - Fatal编程技术网

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();
    }
}