word1 = ['a','b','c','d'];
word2 = ['x','y','z'];
我希望使用这七个字母的组合生成唯一字,但条件是abcd,xyz顺序不应更改。它必须有7个字母,没有重复的字母。
例如
axbyczd - Correct
xyabczd - Correct
xayzbcd - Correct
acdxbyz - Wrong //because letter b is not in order by the position.
aybcdxz - Wrong //because letter y is not in order by the position.
我想在 Javascript 中找到更好的解决方案。
我的解决方案就在这里 https://jsfiddle.net/balaphp/5ht2eoh3/
答案 0 :(得分:2)
这就是你需要的吗?
// Return an array of all the possible words made from weaving `word1` and `word2`.
function combine( word1, word2 ) {
// The resulting array.
var words = [];
// Length of the words to put in `words`.
var len = word1.length + word2.length;
// Array of the positions of each letter of `word1`.
// For instance, if `word1` is "abcd" and `word2`is "xyz",
// then the final word will be 7 length. Therefore, to keep
// "a", "b", "c" and "d" in that order, the "a" can be put in
// position from 0 to 3, the "b" in position from a+1 to 4,
// the "c" in position from b+1 to 5 and the "d" from c+1 to
// 6.
var pos = [];
// Array of the letters of the final word. Undefined items are
// free places for letters of `word2`.
var word = [];
// Recursive function.
// First, it calls itself until all the letters of `word1` are set.
// Then, place the letters of `word2` in the left spaces.
function find() {
var a, b, j, k, currentWord;
if (pos.length == word1.length) {
// Letters of `word1` are now spreaded. Let's place the letters of `word2`.
currentWord = word.slice();
for (j = 0 ; j < word2.length ; j++) {
for (k = 0 ; k < len ; k++) {
if (currentWord[k]) continue;
currentWord[k] = word2.charAt(j);
break;
}
}
words.push( currentWord.join('') );
} else {
// Spread letters of `word1`.
// The current letter to place is `word1.charAt( pos.length )`.
// `a` is the first possible position for the current letter of `word1`.
// `b` is the last possible position.
a = 0; // The first letter can be set at position 0.
if ( pos.length > 0 ) {
// If it is not the first letter, the first
// available position is the current position of
// the previous letter, plus one.
a = pos[pos.length - 1] + 1;
}
// The last position must keep egnough space for remaining letters.
b = len - word1.length + pos.length;
// Put the current letter on every possible places.
for (j = a ; j <= b ; j++) {
// Put the current letter at position `j`.
pos.push( j );
word[j] = word1.charAt( pos.length - 1 );
// Recurse to place next letters.
find();
// Backtrack for next case.
word[j] = undefined;
pos.pop();
}
}
}
// Starting recursion.
find();
return words;
}
// Here is a example of how you can use the `combine` function.
function start() {
var words = combine( 'abcd', 'xyz' );
document.getElementById('out').textContent = words.join("\n");
}
在jsfiddle上查看它。
主要思想是首先放置word1的字母,然后放置word2的字母。
答案 1 :(得分:1)
具有暴力的版本,首先获取所有组合,然后在推送到结果集之前在arrays.every(...)
中查找规则。这适用于两个以上的数组。
function combine(arrays) {
function c(l, r) {
var i, ll;
if (!l.length) {
arrays.every(function (a) {
return a.every(function (b) {
var p = r.indexOf(b);
if (p > this.last) {
this.last = p;
return true;
}
}, { last: -1 });
}) && result.push(r);
return;
}
for (i = 0; i < l.length; i++) {
ll = l.slice();
c(ll, r.concat(ll.splice(i, 1)));
}
}
var array = arrays.reduce(function (a, b) { return a.concat(b); }),
result = [];
c(array, []);
return result;
}
var result1 = combine([['a', 'b', 'c', 'd'], ['x', 'y', 'z']]);
var result2 = combine([['a', 'b', 'c', 'd'], ['x', 'y', 'z'], [1, 2]]);
document.write('<pre>length: ' + result1.length + ' ' + JSON.stringify(result1, 0, 4) + '</pre>');
document.write('<pre>length: ' + result2.length + ' ' + JSON.stringify(result2, 0, 4) + '</pre>');
&#13;
答案 2 :(得分:1)
function processPermute(numberArr,beginLetters) {
var permArr = [];
var usedChars = [];
function permute(input) {
var i, ch;
for (i = 0; i < input.length; i++) {
if(usedChars.length == 0 || beginLetters.indexOf(usedChars[0]) !== -1){
ch = input.splice(i, 1)[0];
usedChars.push(ch);
if (input.length == 0) {
permArr.push(usedChars.slice());
}
permute(input,beginLetters);
input.splice(i, 0, ch);
usedChars.pop();
}
}
};
permute(numberArr);
return permArr
}
function validateRule(wordNumber, word) {
var wordStr = word.join('');
var wordCheckArr = [];
if(!(wordNumber[0] === 'a' || wordNumber[0] === 'x')){
return false;
}
for (var i = 0; i < wordNumber.length; i++) {
if (word.indexOf(wordNumber[i]) !== -1) {
wordCheckArr.push(wordNumber[i]);
}
}
return (wordCheckArr.join('') === wordStr);
}
function findWords(words, rules) {
var letters = [];
var beginLetters = [];
words.forEach(function(word) {
beginLetters.push(word[0]);
letters = letters.concat(word);
});
var allWords = processPermute(letters,beginLetters);
var rightWords = [];
for (var j = 0; j < allWords.length; j++) {
var result = 1;
for (var k = 0; k < rules.length; k++) {
if (validateRule(allWords[j], rules[k])) {
result *= 1;
} else {
result *= 0;
}
}
if (result) {
rightWords.push(allWords[j].join(''));
}
}
return rightWords;
}
var words = findWords([
['a', 'b', 'c', 'd'],
['x', 'y', 'z']
], [
['a', 'b', 'c','d'],
['x', 'y', 'z']
]);
document.write('<pre>'+words.join("\n")+'</pre>');
//min execution time 10ms