繁体   English   中英

如何使此组合/排列方法递归?

[英]How do I make this combinations/permutations method recursive?

我有一个字符串数组列表,希望将所有可能的组合存储到另一个集合中。

例如:

[air,bus,car]
->
[air]
[bus]
[car]
[air,bus]
[air,car]
[bus,air]
[bus,car]
[car,air]
[car,bus]
[air,bus,car]
[air,car,bus]
...
[car,bus,air]

重复并不重要。 我现在拥有的代码是:

public ArrayList<String> comb(ArrayList<String> wrds, ArrayList<String> str, int size)
{
    ArrayList<String> s = new ArrayList<String>();
    s.addAll(str);
    if(size != a1.size())
    {
        Iterator e = a1.iterator();
        while(e.hasNext())
        {
            s.add((String)e.next());
        }
        size++;
    }
}

我试图让它递归调用自己,以便它可以存储组合。 我可以在代码中缺少什么地方或哪一部分方面获得任何帮助吗?

鉴于这是家庭作业,因此我将尝试为您提供答案的背景。

解决此问题的关键是使用递归。

首先假设您的数组中有两个项目。 您可以删除第一个项目以得到您的第一个组合。 将剩余的项目添加到第一项将为您提供第二种组合。 删除第二项将为您提供第三种组合。 添加剩余的项目给您第四组合。 如果您有["air", "bus"]它将类似于:

["air"]
["air", "bus"]
["bus"]
["bus", "air"]

返回的方法可能类似于:

String[][] combinations(String[] strings)

需要注意的重要事项是,可以将包含单个字符串的数组传递给此方法,并且它可以返回其中包含单个字符串的数组的数组。

这个问题有点复杂,因为您必须保持字符串组合的计数,因此在解决这个问题之前,了解递归很重要。

想象一下,您想编写一个将两个数字相乘并将它们相乘的乘法方法,但是您只能使用加法和减法。 您可以编写一个递归函数,将一个数字添加到自身,直到另一个数字达到退出条件,例如:

public int multiply(int value1, int value2) 
{
  if (value1 > 1) 
  {
    int remaining = value1 - 1;
    return value2 + multiply(remaining, value2);
  }
  else 
  {
    return value2;
  }
}

您可以对数组执行相同的操作,只是在值命中值为1时退出而不是在数组包含一项时退出,例如:

public String[][] combinations(String[] strings) 
{
  if (strings.length > 1) 
  {
    ...
  }
  else 
  {
    return new String[][]{strings};
  }
}

由于Java API的原因,使用java.util.List而不是数组要容易得多,因此您需要执行以下操作:

public List<List<String>> combinations(List<String> strings) 
{
  if (strings.size()> 1) 
  {
    ...
  }
  else 
  {
    List<List<String>> result = new ArrayList<List<String>>();
    result.add(strings);
    return result;
  }
}

现在是...那很重要。 您需要保留一个列表列表,该列表将作为结果并遍历strings 对于每个字符串可以是字符串添加到结果,然后你需要创建一个子列表即减去当前字符串,您可以使用它调用combinations方法再次遍历结果将当前字符串包含每个列表。 在代码中,它看起来像:

public List<List<String>> combinations(List<String> strings) 
{
  if (strings.size() > 1) 
  {
    List<List<String>> result = new ArrayList<List<String>>();

    for (String str : strings) 
    {
      List<String> subStrings = new ArrayList<String>(strings);
      subStrings.remove(str);

      result.add(new ArrayList<String>(Arrays.asList(str)));

      for (List<String> combinations : combinations(subStrings)) 
      {
        combinations.add(str);
        result.add(combinations);
      }
    }

    return result;
  }
  else 
  {
    List<List<String>> result = new ArrayList<List<String>>();
    result.add(new ArrayList<String>(strings));
    return result;
  }
}

总之,您要做的是将字符串列表缩减为单个项目,然后将其与前面的项目组合在一起,以在线程返回调用堆栈时产生所有可能的组合。

public static void combination(Object[] array){
         for(int x = 0; x < (1 << array.length); x++){
             System.out.print("[");
             for(int y = 0; y < array.length; y++){
                 if(checkIsOn(x, y){
                    System.out.print(array[y]);
                 }
             }
             System.out.println("]");
         }
    }

    public static boolean checkIsOn(int mast, int position){
         return (mast & (1 << position) > 0);
    }

使用列表作为递归函数的参数。 您可以使用新列表从自身内部调用该函数,该列表包含除第一项以外的所有内容。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM