let's say I have simple 2d array
let array2d = [
['a','a','b'],
['a','b','c'],
['a','c','a']
]
and a simple string with random length, for example:
let string = 'abc';
How can I find all possible combinations of that string in given array where order matters?
so in this example result should be like that:
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']
],
]
I have some thoughts on this one but i'm really not sure about those.
Fun little exercise actually, your thought nr. 2 was in the right direction. What I did was splitting up the task in two, 1. finding all the character locations, 2. recursively put together all the combinations.
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; }
I dont think this is the optimal way of doing it, so if speed is of the essence, you might need to optimize it, or if anybody else can help out?
I dont think I implemented the function recursiveFindAllCombinations correctly, since it uses the global variable result, I just didn't manage to figure out how to incorporate it with the recursive function, let me know if you can!
Changed the function recursiveFindAllCombinations to take into account the values must be in the desired order.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.