嵌套循环的可变数量

7 java loops

我在java中做了一个单词解码器.现在我有一个程序,可以打印从3个或更多字母(没有重复)的单词中选择的3个字母的所有重新排列.例如,如果参数是abcd,它将打印出:

[[abc,abd,acb,acd,adb,adc,bac,bad,bca,bcd,bda,bdc,cab,cad,cba,cbd,cda,cdb,dab,dac,dba,dbc,dca,dcb] ]

我正在使用排列填充2D数组列表.现在,2D数组中只有一个数组,其中包含3个字母的排列.我希望2D数组具有1个字母,2个字母,3个字母等的permations数组,停止在单词的长度.问题是我需要一个可变数量的嵌套for循环来完成这个.对于3个字母的排列,我有3个嵌套for循环.每个循环遍历参数中的字母.

public static void printAllPermuations(String word)
{
    int len = word.length();
    ArrayList<String> lets = new ArrayList<String>();
    //this array of letters allows for easier access
    //so I don't have to keep substringing
    for (int i = 0; i < len; i++)
    {
        lets.add(word.substring(i, i + 1));
    }

    ArrayList<ArrayList<String>> newWords = new ArrayList<ArrayList<String>>();
    newWords.add(new ArrayList<String>());
    for (int i = 0; i < len; i++)
    {
        for (int j = 0; j < len; j++)
        {
            for (int k = 0; k < len; k++)
            {
                if (i != j && i != k && j != k)
                //prevents repeats by making sure all indices are different
                {
                    newWords.get(0).add(lets.get(i) + lets.get(j) + lets.get(k));
                }
            }
        }
    }
    System.out.println(newWords);
}
Run Code Online (Sandbox Code Playgroud)

我看过其他帖子,我听说递归可以解决这个问题.不过,我不知道如何实现这一点.而且我也看到了一些我不理解的复杂解决方案.我要求最简单的解决方案,无论是否涉及递归.

DrY*_*Yap 5

使用递归方法,您可以将循环之一放在函数中,将循环参数传递给该函数。然后从函数的循环中,它调用它来嵌套另一个循环。

void loopFunction(ArrayList<ArrayList<String>> newWords, int level) {
    if (level == 0) { // terminating condition
        if (/* compare the indices by for example passing down a list with them in  */)
        {
            newWords.get(...).add(...);
        }
    } else {// inductive condition
        for (int i = 0; i < len; i++) {
            loopFunction(newWords, level-1);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,对于您的示例,您需要 3 个级别的递归,因此您可以使用以下命令开始递归:

loopFunction(newWords, 3);
Run Code Online (Sandbox Code Playgroud)

编辑

由于您一直遇到问题,这里是一个工作版本。它保留了一个索引列表以进行比较,并随着它的进行构建字符串。将重新排列的单词添加到每个级别的 2D 数组中以获得所有单词长度。使用递归,最容易从功能上思考而不是改变并保持变量不变(不可改变)。这段代码主要是这样做的,尽管indices为了方便起见,我更新而不是创建一个新副本。

void loopFunction(ArrayList<String> lets, ArrayList<ArrayList<String>> newWords, int level, ArrayList<Integer> indices, String word) {
    if (level == 0) { // terminating condition
        return;
    } else { // inductive condition
        for (int i = 0; i < lets.size(); i++) {
            if (!indices.contains(i)) { // Make sure no index is equal
                int nextLevel = level-1;
                String nextWord = word+lets.get(i);

                newWords.get(level-1).add(nextWord);

                indices.add(i);
                loopFunction(lets, newWords, nextLevel, indices, nextWord);
                indices.remove((Integer) i);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)