Javascript 数组交替数据排序

Javascript 数组交替数据排序,javascript,sorting,Javascript,Sorting,给定一个数组,我需要重新排列元素,以便没有两个相邻的元素是相同的。顺序无关紧要 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']; 规则是:下一项永远不应等于上一项 更新 更多规则: 第一件东西永远不要碰,留着吧 其余的相等项应该在末尾

给定一个数组,我需要重新排列元素,以便没有两个相邻的元素是相同的。顺序无关紧要

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'];
规则是:下一项永远不应等于上一项

更新

更多规则:

  • 第一件东西永远不要碰,留着吧
  • 其余的相等项应该在末尾

这里您修改了Durstenfeld洗牌算法:

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;
}
函数shufflearlay(数组){
对于(var i=array.length-1;i>0;i--){
var j;
var计数=0;
做{
j=数学地板(数学随机()*(i+1));
计数++;
}而(i!=array.length&&array[i+1]==array[j]&&count<500);
var-temp=数组[i];
数组[i]=数组[j];
数组[j]=温度;
}
返回数组;
}
这里唯一能出现的是第一个字母可能等于第二个字母。但它很容易检查和修复

下面是解决上述问题的工作示例:

(函数(){
变量列表=['a'、'c'、'c'、'a'、'b'、'b'];
var sortedList=list.sort();
var shuffleArray=函数(数组){
对于(var i=array.length-1;i>0;i--){
var j;
var计数=0;
做{
j=数学地板(数学随机()*(i+1));
计数++;
}而(i!=array.length&&array[i+1]==array[j]&&count<500);
var-temp=数组[i];
数组[i]=数组[j];
数组[j]=温度;
}
如果(array.length>1&&array[0]==array[1]){
var-temp=数组[0];
数组[0]=数组[array.length-1];
数组[array.length-1]=临时值;
}
返回数组;
}
document.getElementById('randomize')。onclick=function(e){
document.getElementById('result').innerHTML=shufflarray(list.join)('');
};
})();



随机化
另一种方法是建立一个列表,用于计算输入字符串中每个字符的出现次数,按字符代码对该出现次数列表进行排序,并通过迭代出现次数列表生成与输入字符串长度相同的新字符串

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');
函数洗牌(src){
if('string'!=typeof src){
抛出新错误(“无效的源字符串”);
}
如果(src.length<3){
返回src;
}
var countersByChar={};
var countersList=[];
//步骤1:统计每个字符出现的次数。
对于(变量i=0;i'+shuffle(src));
}
测试(“accabb”);
测试(“acccca”);
下面是一个工作示例:

函数洗牌(src){
if('string'!=typeof src){
抛出新错误(“无效的源字符串”);
}
如果(src.length<3){
返回src;
}
var countersByChar={};
var countersList=[];
//步骤1:统计每个字符出现的次数。
对于(变量i=0;i'+shuffle(src));
}
测试(“accabb”);
测试(“acccca”)编辑:
此答案不考虑在发布此答案后添加到问题中的两条规则


这是一个幼稚的回答,我不知道性能、效率或优化,但这可以完成工作

对于一个用例,它与您期望的不匹配:

给定数组:
[“a”、“c”、“c”、“c”、“c”、“a”]

预期->:
[“a”、“c”、“a”、“c”、“c”、“c”]

结果--->:
[“c”、“a”、“c”、“c”、“a”、“c”]

我认为预期目标不尊重您提供的规则:

下一项从不应与上一项相同

但结果更尊重规则


我希望这对你有帮助

/*调试目的*/
var el=document.getElementById('el');
var j=JSON.stringify;
变量日志=函数(val){
控制台日志(val);
el.innerHTML+='

好的,我找到了一个解决方案并按预期工作

var alternate=函数(列表){
var指数=0;
var list_size=list.length;
变量过程=函数(l
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);
};