¿Qué es 全排列
Le?
Esta parte proviene de la Enciclopedia Baidu
Tome cualquier m (m≤n) elementos de n elementos diferentes y colóquelos en un cierto orden, lo que se denomina disposición de tomar m elementos de n elementos diferentes. Cuando m = n, todas las permutaciones se denominan permutaciones completas.
Viaje mental
Según 排列组合
los conceptos matemáticos , ¿cómo hacer un arreglo total?
Supongamos que hay una matriz String [] {"Lago Dongting", "Lago Poyang", "Lago Taihu", "Lago Hongze"}
Ahora necesita instalar una nueva matriz de cuatro elementos Array [4], puede seguir los pasos a continuación:
- Continúe y colóquelo en Array [0], tenemos cuatro opciones;
- Vaya a Array [1] y colóquelo de nuevo, tenemos tres opciones;
- Ve a Array [2] y colócalo de nuevo Tenemos dos opciones;
- Vaya a Array [3] y colóquelo nuevamente, tenemos una opción;
¿Transformarse en lenguaje de programación?
- Hay cuatro opciones para Array [0], por lo que necesitamos usar un bucle for para enumerar las cuatro opciones;
- Cuando Array [0] ha hecho una elección (un bucle for), Array [1] tiene tres elementos para elegir. Continuamos usando el bucle for para enumerar las tres opciones;
- Cuando Array [1] termina una elección (un bucle for), Array [2] tiene dos elementos para elegir. Seguimos usando el bucle for para enumerar ambas opciones;
- Cuando Array [2] termina una elección (un bucle for), Array [3] tiene un elemento para elegir. Seguimos usando el bucle for para enumerar todas las opciones;
¿Se siente como el efecto de pegar y copiar arriba? Por favor recuerde este sentimiento. Cuando este sentimiento aparezca, podemos resolver el problema de forma recursiva.
Ejemplo de código
递归
Es el core, se comenta el código, sube:
public class FourLakes {
public static void main(String[] args) throws InterruptedException {
//待放置元素的数组
String[] out = new String[4];
//待计算排列组合的数组
String[] lakes = new String[]{
"洞庭湖", "鄱阳湖", "太湖", "洪泽湖"};
//放置元素的索引从0开始
calc(out, 0, lakes);
}
/**
* 你可能惊讶于代码如此简洁
* 本宝宝花费了一下午的时间想出来的
* 会不会笨了点。。。。。。。。。
* @param out 待放置元素的数组
* @param outIndex 当前要放置元素的位置
* @param data 待拿取元素的数组
*/
private static void calc(String[] out, int outIndex, String[] data) {
//递归退出的条件
//当放置元素的索引大于放置数组长度后,退出
if (outIndex >= out.length) {
System.out.println(Arrays.toString(out));
return;
}
//声明一个缓存数组用,
//作用是:当从 data 中取完元素后,将剩余元素copy 到其中,因为已经取出了一个元素,所以缓存数组大小要-1
String[] temp = new String[data.length-1];
//此处循环的意思就是,data 数组有几个元素就有几种取法
for (int i = 0; i < data.length; i++) {
//取元素,放置到指定的位置
out[outIndex] = data[i];
//从取元素的位置向前看,看看是不是有剩余的元素,然后拷贝到缓存数组中
System.arraycopy(data, 0, temp, 0, i);
//从取元素的位置向后看,看看是不是有剩余的元素,然后拷贝到缓存数组中
System.arraycopy(data, i + 1, temp, i, temp.length - i);
//放置数组不变,将要元素的放置位置+1,将缓存数组作为新的 data
//递归执行
calc(out, outIndex + 1, temp);
}
}
}