String Permutations解释?

时间:2013-03-23 15:25:11

标签: java string

我正在查找如何执行String Permutations并找到下面的解决方案。但是我在理解所使用的逻辑时遇到了麻烦。特别是这条线。 for(final String permutation:Permuatations(subList(head,words)))从我可以告诉作者调用一个函数自身“Permutations”来执行subList函数,这很难很难缠头。谁能让我对我更清楚一点?任何指导都将非常感谢。

public static void main (String [] args)
    {
        for(final String s: Permuatations(Arrays.asList("This ","is ","String ")))
                {
            System.out.println("6. THE FINAL OUTPUT " +s);
                }
    }

    public static List<String> Permuatations(final List<String> words)
    {
        final List<String> perms = new ArrayList<String>();
        if (words.size() == 1)
        {
             perms.add(words.get(0));
             System.out.println("3. permuatations if words " + words);
             System.out.println("4. PERMS LIST " + perms);
        }

        else
        {
            for(final String head : words)
            {
                for(final String permutation : Permuatations(subList(head,words)))
                {
                    perms.add(head + permutation);
                    System.out.println("5 .SubList HEAD " + head + " PERMUATATION " + permutation  + " Word Size " + words.size() );
                }
            }
        }
        return perms;
    }


public static List<String> subList(final String elementToRemove, final List<String> elements)
{
    final List<String> subList = new ArrayList<String>();
    for(final String s : elements)
    {
        //System.out.println(" 1. STRING s " + s + " ELEMENTS " + elements);
        if(!s.equals(elementToRemove))
        {
            System.out.println(" 1. STRING S " + s + " ELEMENTS " + elements);
            subList.add(s);
            System.out.println("2 STRING S " + s + " TO SUBLIST " + subList);
        }


    }

    return subList;
}

3 个答案:

答案 0 :(得分:2)

这正是他们正在做的事情。它被称为递归,而且,首先很难包裹你的头。想象一下你有字符串:

A B C D

实际上,你要做的是依次选择每个字符串然后查找剩余字符串的所有排列,并在你的字符串前面添加。

Choose A, get all permutations of {B,C,D} and append A. 
Choose B, get all permutations of {A,C,D} and append B. 
Choose C, get all permutations of {A,B,D} and append C. 
Choose D, get all permutations of {A,B,C} and append D. 

现在,我们的子问题看起来非常相似,但规模较小。这是递归的核心。解决问题,找到一种方法将其变成问题的较小版本。现在,继续把它变成一个小问题,直到它变得微不足道。现在我们必须弄清楚如何生成3个字符串的排列。

Permute(A B C) 
Choose A, get all permutations of {B,C} and append A.
Choose B, get all permutations of {A,C} and append B.
Choose C, get all permutations of {A,B} and append C.

结构相同,但问题较小。所以更进一步。我们如何进行置换(A B)

Permute(A B) 
Choose A, get all permutations of {B} and append A.
Choose B, get all permutations of {A} and append B.

所以现在我们只需要换一个字符串。那是微不足道的。

Permute(A)
A

现在我们有了一种方法来置换大小为1的字符串列表,并且我们已经定义了如何通过置换大小为N-1的列表来置换大小为N的列表。因此,我们可以通过使用稍微小一点的问题调用自己来置换任何大小&gt; = 1的列表。这就是递归之美。您只需定义如何解决最小的问题,以及如何使用该解决方案构建更大的解决方案,并以此为基础。

答案 1 :(得分:0)

这是一个递归算法,它基本上将数组中的每个元素作为第一个元素,然后在没有该元素的情况下向其添加调用自身的输出。

取3个元素A,B和C并遍历逻辑,让我们调用我们的函数perm

所以,我们想要

perm({A, B, C})

这等于

A + perm({B, C})
B + perm({A, C})
C + perm({A, B})

再次展开

A + B + perm({C})
A + C + perm({B})
B + A + perm({C})
B + C + perm({A})
C + A + perm({B})
C + B + perm({A})

作为perm({X}) = X我们最终得到了

A + B + C
A + C + B
B + A + C
B + C + A
C + A + B
C + B + A

答案 2 :(得分:0)

使用的方案是“分而治之”。它的基本思想是将一个大问题分解为一组应用相同机制的小问题,直到达到问题的“原子”水平。换句话说:大小为n的问题被分解为n个连续大小为n的问题。在底部有一种处理大小1(或任何其他常数)问题的简单方法。这通常是使用递归(如Calgar99)指出的那样完成的。

这个计划的一个非常好的例子也会让你感到头疼的是“河内之塔”。检查一下,这种方法的聪明才智会打动你。

对于所呈现的代码:n个单词的排列是n-1个单词与n个原始单词中的每一个的排列的串联。这个递归定义代表了一个非常优雅的解决方案。