Java の完全な置換再帰関数、1 から 5 までのすべての非反復置換、for ループ呼び出しの再帰関数の説明

1.フルアレンジメント

        これは、数値セットのすべての順列です。たとえば、12345 には、12354、12435、13245などのすべての順列が含まれます。

2. 副次問題とは何ですか

        テキスト表現が明確ではないかもしれませんが、プログラミングの観点から見ると、関数は実際にはサブ問題です。つまり、再帰関数は毎回 1 回呼び出されるため、呼び出される関数はサブ関数です。

3. 最初にコードを入力し、その後に説明を入力します


import java.util.Arrays;

public class Main3 {
    static int flag = 0;//记录次数

    public static void main(String[] args) {
        int[] p = { 1, 2, 3, 4, 5 };//1~5数组

        Permutations(p, 0, p.length);//进行全排列的函数,每一个全排列函数就是一个子问题
        System.out.println(flag + "种");
    }
    /*
     * 输入p数组
     * start是子问题的开始位置
     * end是子问题的总长度
     */
    private static void Permutations(int[] p, int start, int end) {
        /*
         * 首先判断每个子问题是否到最后只剩自己和自己进行交换位置了
         * 如果是则是其中一个排列,直接输出
         */
        
        if (start == end) { 
            flag++;
            System.out.println(Arrays.toString(p));
            return;
        }

        for (int i = start; i < end; i++) {
            /*
             * 自己和自己交换位置或相邻交换位置
             * 当最后只剩下自己和自己交换位置时那么当前子问题将结束
             * 返回到上一个子问题
             * 
             */
            int temp = p[i]; 
            p[i] = p[start];
            p[start] = temp;
            Permutations(p, start + 1, end);
            /*
             * 每一个子问题结束时都要将交换后的排序还原到上一个子问题排序的样子
             * 这是为了不影响下一个子问题的交换排列
             */
            temp = p[i];
            p[i] = p[start];
            p[start] = temp;
        }
    }
}

演算結果

3. forループの機能の意味と実行処理は何ですか?

        多くの友人は、この for ループが何をしているのか理解していません。実際、私はこれに長い間困惑していましたが、いくつかのアルゴリズムの問​​題を解いて、ようやく理解できました。

例を挙げる

if (start == end) { 
            flag++;
            System.out.println(Arrays.toString(p));
            return;
        }
for (int i = start; i < end; i++) {
            
            int temp = p[i]; 
            p[i] = p[start];
            p[start] = temp;
            Permutations(p, start + 1, end);
          
            temp = p[i];
            p[i] = p[start];
            p[start] = temp;
        }

上記のコード配列 [1,2,3,4,5] の長さは 5 (end=5) ですstart=0 と仮定して 0 から開始すると、 i も 0 に等しくなります。このとき、位置は次と交換されます。独自の要素、交換 その後、一度独自の関数を呼び出して、次の位置と交換できる可能性があるかどうかを確認します。start が 0に等しいため、明らかに存在します。 , start=2などと副問題が生成されます。 start+1 の位置を通過すると、start+1 はstart=0 の副問題になります。

次に、この時点では start=1、i は 1 に等しいため、それ自体と位置を交換し、サブ問題の生成を続けます。つまり、start=2、start=2 は自身の要素と位置を交換してサブ問題を生成します。 -problem start=3、start=3 とその独自の要素交換位置でサブ問題 start=4 が生成され、最後に start=4 と独自の要素交換位置でサブ問題 start=5 が生成されます。この時点では、 start=4 のサブ問題 start=5 は長さ 5 に等しく、start=4 はstart=5 の要素と位置を交換できません。つまり、現時点では、start=4 にはサブ問題が 1 つだけあります。 、 start=5、start=5 にはサブ問題がありません。次に、start=5 Question でサブ問題を直接終了し、最初の配置 [1,2,3,4,5] を出力し、次に次の位置交換を出力します。このサブ質問の終了後は、start=4 と start=4 の要素の交換です。

サブ問題 start=5 が終了し、start=4 の問題も終了します。次に、start=3、i=start=3 の問題を解決します (end=5、i<5、次に i++ であるため)。 , get i= 4. このとき、start=3 と i=4の要素を交換して [1,2,3,5,4] を取得します 交換後、start=3 が関数を呼び出してサブルーチンを生成します-problem start=4 ですが、今回は start=4 は配置 [1,2,3,5,4] を解き、start=4 は最後のサブ問題 start=5 を生成し、[1,2,3] を直接出力します。 ,5,4], start=4 問題は再び終了です。問題に戻り続けます start=3、この時点では i=4, start=3, i++, i=5 を取得します (i<5 が満たされない場合) 、サブ問題 start=3 が終了し、start=3 および i=4 位置を交換し、[1,2,3,5,4] 配列を [1,2,3,4,5] に復元します。

 start=3 の問題が解決された後、前の問題 start=2 に戻って解決します。これは上記の操作と同じなので、ここでは続行しません。実際、この for ループは次のとおりであることがわかります。位置交換の副問題が発生し、その副問題の中に副問題が生成されます 例えば、上記の仮定が i=start=0 で始まる場合、 i=start= の副問題が生成されます1 が生成され、start=1 の副問題は i=start= の副問題が生成されます。 2 の副問題、start=2 の副問題は i=start= の副問題が生成されます。 3 では、start=3 の部分問題は i=start=4 の部分問題を生成するため、最初の段階 i=start=0 start=1、start=2、start=3、および start=4 の部分問題そして、start=0 の部分問題がすべて解けると i++ に進み、start=0、i= 1 の部分問題で、引き続き start=1、start=2、 start=3、start=4など。

おすすめ

転載: blog.csdn.net/m0_59799878/article/details/129414092