假设我有简单的2d数组
let array2d = [
['a','a','b'],
['a','b','c'],
['a','c','a']
]
和一个随机长度的简单字符串,例如:
let string = 'abc';
如何在给定顺序重要的给定数组中找到该字符串的所有可能组合?
因此在此示例中,结果应为:
result = [
[
['*','a','*'],
['a','b','*'],
['a','c','a']
],
[
['*','a','*'],
['a','b','c'],
['a','*','a']
],
[
['*','a','b'],
['a','*','*'],
['a','c','a']
],
[
['*','a','b'],
['a','*','c'],
['a','*','a']
],
[
['a','*','*'],
['a','b','*'],
['a','c','a']
],
[
['a','*','*'],
['a','b','c'],
['a','*','a']
],
[
['a','*','b'],
['a','*','*'],
['a','c','a']
],
[
['a','*','b'],
['a','*','c'],
['a','*','a']
],
[
['a','a','b'],
['*','*','*'],
['a','c','a']
],
[
['a','a','b'],
['*','*','c'],
['a','*','a']
],
]
我对此有一些想法,但是我真的不确定。
答案 0 :(得分:0)
实际上,您很少想运动。 2方向正确。我所做的就是将任务分成两个部分:1.查找所有角色位置,2.将所有组合递归组合。
let array2d = [["a", "a", "b"], ["a", "b", "c"], ["a", "c", "a"]];
let string = "abc";
var chars = string.split(""); //Convert string to [ 'a', 'b', 'c' ]
var dataAsString = array2d.map(function(d) {
return d[0] + d[1] + d[2];
});
let concatedArrayString = dataAsString.join(""); //Convert array2d to "aababcaca"
let locations = findAllCharLocations(chars, concatedArrayString); // returns { a: [ 0, 1, 3, 6, 8 ], b: [ 2, 4 ], c: [ 5, 7 ] }
var result = [];
recursiveFindAllCombinations(0, array2d, locations, []);
console.log(result);
// The result is:
// [ [ [ '*', 'a', '*' ], [ 'a', 'b', '*' ], [ 'a', 'c', 'a' ] ],
// [ [ '*', 'a', '*' ], [ 'a', 'b', 'c' ], [ 'a', '*', 'a' ] ],
// [ [ '*', 'a', 'b' ], [ 'a', '*', '*' ], [ 'a', 'c', 'a' ] ],
// [ [ '*', 'a', 'b' ], [ 'a', '*', 'c' ], [ 'a', '*', 'a' ] ],
// [ [ 'a', '*', '*' ], [ 'a', 'b', '*' ], [ 'a', 'c', 'a' ] ],
// [ [ 'a', '*', '*' ], [ 'a', 'b', 'c' ], [ 'a', '*', 'a' ] ],
// [ [ 'a', '*', 'b' ], [ 'a', '*', '*' ], [ 'a', 'c', 'a' ] ],
// [ [ 'a', '*', 'b' ], [ 'a', '*', 'c' ], [ 'a', '*', 'a' ] ],
// [ [ 'a', 'a', '*' ], [ '*', 'b', '*' ], [ 'a', 'c', 'a' ] ],
// [ [ 'a', 'a', '*' ], [ '*', 'b', 'c' ], [ 'a', '*', 'a' ] ],
// [ [ 'a', 'a', 'b' ], [ '*', '*', '*' ], [ 'a', 'c', 'a' ] ],
// [ [ 'a', 'a', 'b' ], [ '*', '*', 'c' ], [ 'a', '*', 'a' ] ],
// [ [ 'a', 'a', '*' ], [ 'a', 'b', '*' ], [ '*', 'c', 'a' ] ],
// [ [ 'a', 'a', '*' ], [ 'a', 'b', 'c' ], [ '*', '*', 'a' ] ],
// [ [ 'a', 'a', 'b' ], [ 'a', '*', '*' ], [ '*', 'c', 'a' ] ],
// [ [ 'a', 'a', 'b' ], [ 'a', '*', 'c' ], [ '*', '*', 'a' ] ],
// [ [ 'a', 'a', '*' ], [ 'a', 'b', '*' ], [ 'a', 'c', '*' ] ],
// [ [ 'a', 'a', '*' ], [ 'a', 'b', 'c' ], [ 'a', '*', '*' ] ],
// [ [ 'a', 'a', 'b' ], [ 'a', '*', '*' ], [ 'a', 'c', '*' ] ],
// [ [ 'a', 'a', 'b' ], [ 'a', '*', 'c' ], [ 'a', '*', '*' ] ] ]
//Recursivly find all the combinations of a character at index, character array which is modified,
function recursiveFindAllCombinations(
charIndex,
characterArray,
locations,
currentCharIndexArray
) {
//Copy the character array since we modifying it but dont want the other references to change
let charArray = characterArray.map(function(arr) {
return arr.slice();
});
//The current char
let char = chars[charIndex];
//For each location the character is found
for (var index = 0; index < locations[char].length; index++) {
//Copy the char index array
var newCharIndexArray = currentCharIndexArray.slice();
var isAnOption = true;
//Check and see if the new value is valid compared to the already choosen values.
for (var check = 0; check < newCharIndexArray.length; check++) {
let value = newCharIndexArray[check];
if (value > locations[char][index]) {
isAnOption = false;
}
}
if (isAnOption) {
//Example the first 'a' is found at
// x = 0 % 3 = 0
// y = Math.floor(0 / 3) = 0
let x = locations[char][index] % array2d.length;
let y = Math.floor(locations[char][index] / array2d.length);
//Paint that location as found
charArray[y][x] = "*";
newCharIndexArray.push(locations[char][index]);
//If there is more chars call recursively
if (chars[charIndex + 1]) {
//Use the next character in line
recursiveFindAllCombinations(
charIndex + 1,
charArray,
locations,
newCharIndexArray
);
} else {
//Since no more recursiv calls to do, push a copy of the charArray.
result.push(
charArray.map(function(arr) {
return arr.slice();
})
);
}
//Reset the charArray
charArray[y][x] = char;
}
}
}
//Find all the char locations
//Example returning : { a: [ 0, 1, 3, 6, 8 ], b: [ 2, 4 ], c: [ 5, 7 ] }
function findAllCharLocations(chars, concatedArrayString) {
let charsCopy = chars.slice(0); //Make a copy on the char array.
var locations = {};
//Initiate the locations array { a: [], b: [], c: [] }
for (var charIndex = 0; charIndex < charsCopy.length; charIndex++) {
locations[charsCopy[charIndex]] = [];
}
var counter = 0;
//As long as we havent found all the chars in 2d array continue
while (counter != chars.length) {
//Store the chars which we are done with and remove them after the loop.
var charsToRemove = [];
//Go through each char.
for (var index = 0; index < charsCopy.length; index++) {
let char = charsCopy[index];
//Get the last index of that specific character, if nothing found yet this will be NaN.
let lastIndexOfChar = locations[char][locations[char].length - 1];
//Get the index of the next character
let indexOfChar = concatedArrayString.indexOf(char, lastIndexOfChar + 1);
//If a character was found push it to the location array
if (indexOfChar != -1) {
locations[char].push(indexOfChar);
} else {
//Since the character was not found remove it from the char array and let our counter know one less char to find.
counter++;
charsToRemove.push(char);
}
}
//Do the removal of characters no longer found in the string.
for (var index = 0; index < charsToRemove.length; index++) {
charsCopy.splice(charsCopy.indexOf(charsToRemove[index]), 1);
}
}
return locations;
}
我不认为这是最佳的实现方式,因此,如果速度至关重要,那么您可能需要对其进行优化,或者是否有人可以提供帮助?
我认为我没有正确实现函数recursiveFindAllCombinations,因为它使用了全局变量结果,所以我只是没有弄清楚如何将其与递归函数合并,让我知道是否可以!
更改了函数recursiveFindAllCombinations以考虑到值必须按所需顺序排列。