给定一个数组,我需要重新排列元素,以便没有两个相邻的元素是相同的。排序无关紧要。
var list = ['a','c','c','a','b','b'];
//expected ['a','c','a','b','c','b'];
var listb = ['a','c','c','c','c','a'];
//expected ['a','c','a','c','c','c'];
规则是:下一项永远不应该等于前一项。
更新
更多规则:
答案 0 :(得分:2)
这看起来像一个有趣的问题。
所以如果我没有弄错的话,那就是规则:
我采取了递归方法。 也许这就是你要找的东西?
结果如下:
[' A'' C'' C'' A'' B',& #39; b'] => [' a'''' c',''' a',' C&#39]
[' A'' C'' C'' C'' C',& #39; a'] => [' a'' c',' a',' c'' c',' C&#39]
[' a',' a'' b',' a'] => [' a',' b',' a',' a']
function alternateArray(originalArray) {
var resultArray = [];
var allValuesSame = function(myArray) {
for (var p = 0; p< myArray.length; p++) {
if (myArray[0] != myArray[p]) {
return false;
}
}
return true;
};
var process = function (originalArray, resultArray) {
if (originalArray.length == 0) {
return resultArray;
}
// Find a suitable spot that would respect the alternating requirement
for (var i = originalArray.length -1; i>=0; i--) {
var replaced = false;
for (var j = 1; j<resultArray.length-1; j++) {
if (resultArray[j] && resultArray[j+1]) {
if (resultArray[j] != originalArray[i] && resultArray[j+1] != originalArray[i]) {
resultArray.splice(j+1, 0, originalArray.splice(i, 1)[0]);
replaced = true;
break;
}
}
}
if (replaced) {
continue;
}
// If no suitable spot was found, lets try the end of the resultArray
if (resultArray[resultArray.length-1] != originalArray[i]) {
resultArray.push(originalArray.splice(i, 1)[0]);
continue;
}
if (allValuesSame(originalArray) && originalArray.length > 0) {
// Rule: the rest of equals items should be at the end
for (var z = 0; z < originalArray.length; z++) {
resultArray.push(originalArray[i]);
}
return resultArray;
}
}
return process(originalArray, resultArray)
};
// Rule: keep the first item (Rule)
if (originalArray[0]) {
resultArray.push(originalArray.splice(0, 1)[0]);
}
return process(originalArray, resultArray);
}
console.log(alternateArray(['a','c','c','a','b','b']));
console.log(alternateArray(['a','c','c','c','c','a']));
console.log(alternateArray(['a', 'a', 'b', 'a']));
&#13;
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
&#13;
答案 1 :(得分:0)
在这里你修改了Durstenfeld shuffle算法:
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j;
var count = 0;
do {
j = Math.floor(Math.random() * (i + 1));
count++;
} while(i!=array.length && array[i+1] == array[j] && count < 500);
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
这里唯一可以出现的是第一个字母可能等于第二个字母。但它很容易检查和修复。
以上问题已修复:https://jsfiddle.net/1zeafb31/
(function() {
var list = ['a','c','c','a','b','b'];
var sortedList = list.sort();
var shuffleArray = function(array) {
for (var i = array.length - 1; i > 0; i--) {
var j;
var count = 0;
do {
j = Math.floor(Math.random() * (i + 1));
count++;
} while(i!=array.length && array[i+1] == array[j] && count < 500);
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
if(array.length > 1 && array[0] == array[1]) {
var temp = array[0];
array[0] = array[array.length - 1];
array[array.length-1] = temp;
}
return array;
}
document.getElementById('randomize').onclick = function(e) {
document.getElementById('result').innerHTML = shuffleArray(list).join(' ');
};
})();
<div id='result'></div>
<br>
<button id='randomize'>Randomize</button>
答案 2 :(得分:0)
另一种方法是构建一个列表,用于计算输入字符串中每个字符的出现次数,按字符代码对此出现列表进行排序,并通过迭代事件列表生成一个与输入字符串长度相同的新字符串。 / p>
function shuffle(src) {
if ('string' != typeof src) {
throw new Error('Invalid source string.');
}
if (src.length < 3) {
return src;
}
var countersByChar = {};
var countersList = [];
// STEP 1: Count each character occurrence.
for (var i = 0; i < src.length; ++i) {
var chr = src[i];
var counter = countersByChar[chr];
if (!counter) {
counter = {
chr: chr,
count: 0
};
countersByChar[chr] = counter;
countersList.push(counter);
}
++counter.count;
}
// STEP 2: Sort counters list by character code.
countersList.sort(function(lhs, rhs) {
return lhs.chr.charCodeAt(0) - rhs.chr.charCodeAt(0);
});
// STEP 3: Generate a new permutation.
var charsLeft = src.length;
var p = 0;
var dest = [];
while(charsLeft) {
var c = countersList[p];
dest.push(c.chr);
if (!--c.count) {
countersList.splice(p, 1);
} else {
++p;
}
if (p == countersList.length) {
p = 0;
}
--charsLeft;
}
var result = dest.join('');
return result;
}
function test(src) {
alert('shuffle("' + src + '") => ' + shuffle(src));
}
test('accabb');
test('acccca');
以下是工作示例:https://jsfiddle.net/pbcq2o3y/
function shuffle(src) {
if ('string' != typeof src) {
throw new Error('Invalid source string.');
}
if (src.length < 3) {
return src;
}
var countersByChar = {};
var countersList = [];
// STEP 1: Count each character occurrence.
for (var i = 0; i < src.length; ++i) {
var chr = src[i];
var counter = countersByChar[chr];
if (!counter) {
counter = {
chr: chr,
count: 0
};
countersByChar[chr] = counter;
countersList.push(counter);
}
++counter.count;
}
// STEP 2: Sort counters list by character code.
countersList.sort(function(lhs, rhs) {
return lhs.chr.charCodeAt(0) - rhs.chr.charCodeAt(0);
});
// STEP 3: Generate a new permutation.
var charsLeft = src.length;
var p = 0;
var dest = [];
while(charsLeft) {
var c = countersList[p];
dest.push(c.chr);
if (!--c.count) {
countersList.splice(p, 1);
} else {
++p;
}
if (p == countersList.length) {
p = 0;
}
--charsLeft;
}
var result = dest.join('');
return result;
}
function test(src) {
alert('shuffle("' + src + '") => ' + shuffle(src));
}
test('accabb');
test('acccca');
&#13;
答案 3 :(得分:0)
编辑 : 此答案发布后,此答案不会处理问题中添加的两条规则。
这是一个天真的答案,我不知道性能,效率或优化,但这可以做到这一点。
对于一个用例,它不符合您的期望:
给定数组:["a","c","c","c","c","a"]
expected-&GT; :["a","c","a","c","c","c"]
结果 - - - &gt; :["c","a","c","c","a","c"]
我认为预期不尊重您提供的唯一规则:
下一项 从不 应该等于之前的
但结果更尊重规则!
我希望这会对你有帮助。
/* debug purpose */
var el = document.getElementById('el');
var j = JSON.stringify;
var log = function(val) {
console.log(val);
el.innerHTML += '<div><pre>' + val + '</pre></div>'
};
var tmpl = function(argList, argResult, argExpected){
log( j(argList) + '\n\t become\n' + j(argResult) +
"\n\texpected\n" + j(argExpected) +
" matching : " +
(j(argResult) === j(argExpected) )
);
};
/* Main function */
var Alternate = function(listToAlternate) {
var clone = listToAlternate.slice(0);
var nextNot = function(val, from, arr) {
var idx = from + 1;
for ( idx; idx <= arr.length ; idx++ ) {
if (arr[ idx ] != val && arr[ idx + 1 ] != val) return idx;
}
return from;
};
var prevNot = function(val, from, arr) {
var idx = from - 1;
for ( idx; idx >= 0; idx-- ) {
if ( arr[ idx ] != val && arr[ idx - 1 ] != val) return idx;
}
return from;
};
var len = clone.length;
var prev = '';
var curPos;
var curVal;
var repetition;
for( var i = 0 ; i < len ; i++){
curPos = i;
curVal = clone[ curPos ];
if(curVal == prev){
repetition = clone.splice( curPos , 1)[0];// remove
var nextPos;
if(curPos === len){
nextPos = prevNot(repetition , curPos , clone);// lookFor
} else {
nextPos = nextNot(repetition , curPos , clone);// lookFor
}
clone.splice(nextPos , 0 , repetition); //insert
}
prev = clone[i];
};
prev = '';
curVal = undefined;
curPos = undefined;
repetition = undefined;
for( var i = len-1 ; i>=0 ; i--){
curPos = i;
curVal = clone[ curPos ]
if(curVal == prev){
repetition = clone.splice( curPos , 1)[0]; // remove
var prevPos = prevNot(repetition , curPos , clone); // lookFor
clone.splice(prevPos , 0 , repetition); // insert
}
prev = clone[i];
};
return clone;
};
/* Use case testing */
var list;
var expected;
list = ['a','c','c','a','b','b'];
expected = ['a','c','a','b','c','b'];
result = Alternate( list );
tmpl( list , result , expected);
list = ['a','b','b','a'];
expected = ["a","b","a","b"];
result = Alternate( list );
tmpl( list , result , expected);
list = ['a','a','b','a'];
expected = ["a","b","a","a"];
result = Alternate( list );
tmpl( list , result , expected);
list = ['a','c','c','c','c','a'];
expected = ['a','c','a','c','c','c'];
result = Alternate( list );
tmpl( list , result , expected);
list = ['hello','hello', 'bye','bye','hello'];
expected = ['hello','bye','hello','bye','hello'];
result = Alternate( list );
tmpl( list , result , expected);
list = ['b','b','b','b','a','c','c','a','b','b','b'];
result = Alternate( list );
log( j( list ) + '\n\t become\n' + j( result ) );
list = ['a','c','c','c','a','b','b','z'];
result = Alternate( list );
log( j( list ) + '\n\t become\n' + j( result ) );
div{
border : solid 1px #EEE;
}
<div id='el'></div>
答案 4 :(得分:-1)
好的,我找到了一个解决方案并按预期工作
var alternate = function(list) {
var index = 0;
var list_size = list.length;
var process = function(list_process) {
// Search the next item different, remove and return this.
var serchNextDifferent = function(number) {
for (var i = index+1; i <= list_size; i++) {
if (list_process[i] !== number) {
return list_process.splice(i,1)[0];
}
}
};
// Search the next item different, remove and return this.
var serchPrevDifferent = function(number, index) {
for (var i = index-1; i >= 0; i--) {
if (list_process[i] !== number && list_process[i] !== list_process[index] && number !== list_process[i-1] && i) {
return list_process.splice(i,1)[0];
}
}
};
// Check if the current item and the prev are equals
if (list_process[index-1] === list_process[index]) {
var next = serchNextDifferent(list_process[index]);
if (next) {
list_process.splice(index, 0, next[0]);
} else {
var prev = serchPrevDifferent(list_process[index], index);
if (prev) {
list_process.splice(index-1, 0, prev[0]);
} else {
list_process.push(list_process.splice(index, 1)[0]);
}
}
}
// next
if (list_size-1 !== index) {
index++;
return process(list_process);
} else {
return list_process;
}
};
return process(list);
};
以下是工作示例Link