如何生成可变长度集的所有子集?

时间:2011-11-11 00:21:51

标签: java

我正在尝试编写一个程序来生成java中输入集的所有子集。我想我差不多了。

  • 我必须使用数组(不是数据结构)
  • 输入的数组永远不会超过20

现在,当我运行我的代码时,这就是我得到的:

Please enter the size of A: 3
Please enter A: 1 2 3
Please enter the number N: 3
Subsets: 
{ }
{ 1 }
{ 1 2 }
{ 1 2 3 }
{ 2 3 }
{ 2 3 }
{ 2 }
{ 1 2 }

这是正确的子集数量(2 ^大小),但正如您所看到的那样,它会打印一些重复项而不是某些子集。

我的代码中出错的任何想法?

import java.util.Scanner;

public class subSetGenerator 
{   
    // Fill an array with 0's and 1's
    public static int [] fillArray(int [] set, int size)
    {
        int[] answer;
        answer = new int[20];

        // Initialize all elements to 1
        for (int i = 0; i < answer.length; i++)
            answer[i] = 1;

        for (int a = 0; a < set.length; a++)
            if (set[a] > 0)
                answer[a] = 0;  

        return answer;
    } // end fill array

    // Generate a mask
    public static void maskMaker(int [] binarySet, int [] set, int n, int size)
    {
        int carry;
        int count = 0;
        boolean done = false;

        if (binarySet[0] == 0)
            carry = 0;

        else
            carry = 1;

        int answer = (int) Math.pow(2, size);

        for (int i = 0; i < answer - 1; i++)
        {
            if (count == answer - 1)
            {
                done = true;
                break;
            }

            if (i == size)
                i = 0;

            if (binarySet[i] == 1 && carry == 1)
            {
                binarySet[i] = 0;
                carry = 0;
                count++;
            } // end if

            else
            {
                binarySet[i] = 1;
                carry = 1;
                count++;
                //break;
            } // end else

            //print the set
            System.out.print("{ ");

            for (int k = 0; k < size; k++)
                if (binarySet[k] == 1)
                    System.out.print(set[k] + " ");             

            System.out.println("}");

        } // end for

    } // maskMaker

    public static void main (String args [])
    {
        Scanner scan = new Scanner(System.in);
        int[] set;           
        set = new int[20];
        int size = 0;  
        int n = 0;

        // take input for A and B set
        System.out.print("Please enter the size of A: ");
        size = scan.nextInt();

        if (size > 0)
        {
            System.out.print("Please enter A: ");
            for (int i = 0; i < size; i++)
                set[i] = scan.nextInt();
        } // end if

        System.out.print("Please enter the number N: ");
        n = scan.nextInt();

        //System.out.println("Subsets with sum " + n + ": ");
        System.out.println("Subsets: ");

        System.out.println("{ }");
        maskMaker(fillArray(set, size), set, n, size);

    } // end main

}  // end class

1 个答案:

答案 0 :(得分:0)

i的值总是从0变为N-1然后又变回0.这对于生成每次只需要一次的二进制掩码没有用。如果您考虑一下,只有在生成所有可能的面具i时才需要移动i-1

如果你记得每个数字已经在计算机中以二进制形式在内部表示,并且每次增加它,那么有一种更简单的方法可以做到这一点.Java正在自行添加和携带。寻找bitwise operators