Quiero imprimir todos los subconjuntos de una matriz usando el retroceso en Javascript, mi algoritmo es correcto pero da algunas respuestas inesperadas. Creo que esto está relacionado con el lenguaje javascript.
// this is base function where i am calling recursive function . function solveIt(A,B,C,D,E){ let ans = []; // this is ans array let sub = []; // this is subset array printAllSubset(A,0,sub,ans); // Calling the helper function return ans; // returing anser } // My recursive code function printAllSubset(nums,idx,sub,ans){ if(idx==nums.length){. // This is base condition ans.push(sub); return ans; } // include current index sub.push(nums[idx]); // including the current index printAllSubset(nums,idx+1,sub,ans); // recuring for all possible sub problem // exclude current index sub.pop(); // excluding the current index printAllSubset(nums,idx+1,sub,ans); // recuring for all possible scenerio } const A=[1,2,3]; const res = solveIt(A,B,C); console.log(res) // output I am getting - [ [], [], [], [], [], [], [], [] ] // But the expected output should be - [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
El problema aquí es que está agregando la misma matriz sub a ans y cualquier cambio en sub se refleja dentro de los datos de ans también. Por lo tanto, deberá agregar una copia de sub en su lugar:
const A=[1,2,3]; const res = solveIt(A); console.log(res) // this is base function where i am calling recursive function . function solveIt(A,B,C,D,E){ let ans = []; // this is ans array let sub = []; // this is subset array printAllSubset(A,0,sub,ans); // Calling the helper function return ans; // returing anser } // My recursive code function printAllSubset(nums,idx,sub,ans){ if(idx==nums.length){ // This is base condition ans.push([...sub]); // push a copy of the array return ans; } // include current index sub.push(nums[idx]); // including the current index printAllSubset(nums,idx+1,sub,ans); // recuring for all possible sub problem // exclude current index sub.pop(); // excluding the current index printAllSubset(nums,idx+1,sub,ans); // recuring for all possible scenerio }Construyes para tener la respuesta en ans , pero luego la tiras. Una respuesta es hacer ans una variable global y eliminarla de las llamadas a funciones recursivas:
let ans=[] function solveIt(A){ printAllSubset(A,0,[]); // Calling the helper function } function printAllSubset(nums,idx,sub){ if(idx===nums.length){. // This is base condition ans.push(sub); } // include current index sub.push(nums[idx]); // including the current index printAllSubset(nums,idx+1,sub); // recuring for all possible sub problem // exclude current index sub.pop(); // excluding the current index printAllSubset(nums,idx+1,sub); // recuring for all possible scenerio } El otro es captar el retorno de las llamadas recursivas a printAllSubset :
function solveIt(A){ return printAllSubset(A,0,[],[]); // Calling the helper function } function printAllSubset(nums,idx,sub,ans){ if(idx===nums.length){. // This is base condition ans.push(sub); return ans; } // include current index sub.push(nums[idx]); // including the current index ans=printAllSubset(nums,idx+1,sub,ans); // recuring for all possible sub problem // exclude current index sub.pop(); // excluding the current index ans=printAllSubset(nums,idx+1,sub,ans); // recuring for all possible scenerio return ans; }Las otras respuestas aquí muestran qué estaba mal con su código y cómo solucionarlo. Me gustaría demostrar una forma recursiva más limpia de escribir esto:
const powerset = ([x, ...xs] = []) => x == undefined ? [[]] : powerset (xs) .flatMap (ys => [ys, [x, ...ys]]) console .log (JSON .stringify (powerset ([1, 2, 3]))) Como con toda recursividad, una forma útil de pensar en esto es reconocer que funciona para un caso base, y si cada llamada recursiva avanza hacia un caso base, y si podemos ver que cuando funciona para nuestra llamada recursiva también funciona para nuestra llamada actual, entonces podemos estar seguros de que funciona para todos los casos. Porque powerset ([]) //=> [[]] , funciona para un caso base. Debido a que cada llamada recursiva implica reducir nuestra matriz de entrada en uno, entonces se cumple nuestra segunda condición; eventualmente llegaremos a un caso base. La tercera condición la mostramos con un ejemplo: asumimos que powerset ([2, 3]) produce correctamente [[], [2], [3], [2, 3]] , luego powerset ([1, 2, 3]) rendirá
[[], [2], [3], [2, 3]] .flatMap (ys => [ys, [1, ...ys]])que es lo mismo que
[... [[], [1]], ... [[2], [1, 2]], ... [[3], [1, 3]], ... [[2, 3], [1, 2, 3]]] // `--[]--' `----[2]----' `----[3]----' `------[2, 3]------'que es simplemente
[[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]y así el caso recursivo funciona correctamente. No es difícil demostrar que todos los subconjuntos aparecerán con esta técnica. Simplemente formalizaríamos el ejemplo anterior.
Pero esto significa que esta función capturará con precisión el conjunto de potencia de un conjunto expresado como una matriz JS.