按正态分布(高斯分布)对数字数组进行排序

5

有一个数字数组 setOfNumbers = [0, 3, 3, 2, 7, 1, -2, 9],我希望将其排序,使得最小的数在排序后的数组开头和结尾位置,而最大的数在排序后数组的中间位置,就像这样 sortedSetNumbers = [0, 2, 3, 9, 7, 3, 1, -2]

const setOfNumbers = [0, 3, 3, 2, 7, 1, -2, 9];
const result = [0, 2, 3, 9, 7, 3, 1, -2];

function sortNormal(a, b) {
  return true; // Please, change this line
}

const sortedSetNumbers = setOfNumbers.sort((a, b) => sortNormal(a, b));



if (sortedSetNumbers === result) {
  console.info('Succeeded Normal Distributed');
} else {
  console.warn('Failed Normal Distribution');
}

console.log(sortedSetNumbers);

我相信可以用Array.prototype.sort()方法对这些数字进行排序,但是排序函数应该长成什么样子呢?

编辑:解决方案不一定要使用.sort()。那只是一个想法。


1
也许我对这个分配方式太天真了,但是你是如何确定哪些数字被放在开头,哪些放在结尾的呢?或者这不重要吗? - OliverRadini
没关系,结果不一定要与答案完全相同。我已经手动完成了。步骤是:1)选择最大的数字;2)在左侧集合中找到下一个最大的数字;3)将左右交替附加到结果集中。 - Michael W. Czechowski
@OliverRadini 在左侧最大值和右侧最大值之间的最大数字 - Ankur Shah
@所有人 如果问题不够清晰,而你认为你已经理解了我的问题,请随意编辑问题。 - Michael W. Czechowski
3个回答

6

这可能是最朴素的方法,但它不是简单地左、右、左、右...排序后吗?

const input    = [0, 3, 3, 2, 7, 1, -2, 9];
const expected = [0, 2, 3, 9, 7, 3, 1, -2];

const sorted   = input.slice().sort();
const output   = [];
let side       = true;

while (sorted.length) {
  output[side ? 'unshift' : 'push'](sorted.pop());
  side = !side;
}

console.log(expected.join());
console.log(output.join());

或者简单点说:

const input  = [0, 3, 3, 2, 7, 1, -2, 9];
const output = input.slice().sort().reduceRight((acc, val, i) => {
  return i % 2 === 0 ? [...acc, val] : [val, ...acc];
}, []);

console.log(output.join());


厉害,@Yoshi 和 @NinaScholz,你们俩都很棒! - Michael W. Czechowski

2
稍微不同的方法是按升序对数组进行排序。
获取另一个索引数组,并将奇数值按升序排列到前半部分,将偶数值按降序排列到末尾,使用反转的蝴蝶洗牌算法
然后通过获取已排序索引的值来映射已排序数组。
"Original Answer" 翻译成 "最初的回答"
[-2, 0, 1, 2, 3, 3, 7,  9] // sorted array
[ 1, 3, 5, 7, 6, 4, 2,  0] // sorted indices
[ 0, 2, 3, 9, 7, 3, 1, -2] // rebuild sorted array

var array = [0, 3, 3, 2, 7, 1, -2, 9].sort((a, b) => a - b);

array = Array
    .from(array, (_, i) => i)
    .sort((a, b) => b % 2 - a % 2 || (a % 2 ? a - b : b - a))
    .map(i => array[i]);

console.log(array);


0

这个解决方案并不是非常优雅,但它能够完成它的工作。

const setOfNumbers = [0, 3, 3, 2, 7, 1, -2, 9];
const alternation = alternate();
const sortedSetNumbers = sortNormal(setOfNumbers);

function sortNormal(start) {
  const result = [];
  const interim = start.sort((a, b) => {
    return b - a;
  });

  interim.map(n => {
    if (alternation.next().value) {
      result.splice(0, 0, n);
    } else {
      result.splice(result.length, 0, n);
    }
  });

  return result;
}

function* alternate() {
  let i = true;

  while (true) {
    yield i;
    i = !i;
  }
}

console.log(sortedSetNumbers);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接