Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/377.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 分类比赛种子_Javascript_Sorting - Fatal编程技术网

Javascript 分类比赛种子

Javascript 分类比赛种子,javascript,sorting,Javascript,Sorting,我正在制作一个基于HTML/JS的单/双消元括号web应用程序。我正在努力找出如何从种子队/球员名单中分配第一轮比赛。例如,在8名球员中,第一轮比赛是: 1v8 4v5 2v7 3v6 在更一般的术语中,种子可以被认为是一个数组(因为我通过从数组中弹出种子来分配团队进行比赛): 1,2,3,4,5,6,7,8 需要将其分类为: 1,8,4,5,2,7,3,6 为了澄清这一点,在排序的数组中,较高的种子之间需要有最大的距离,这样在没有混乱的括号中,较低的种子首先被淘汰,而与较高种子的匹配则尽可能晚

我正在制作一个基于HTML/JS的单/双消元括号web应用程序。我正在努力找出如何从种子队/球员名单中分配第一轮比赛。例如,在8名球员中,第一轮比赛是:

1v8 4v5 2v7 3v6

在更一般的术语中,种子可以被认为是一个数组(因为我通过从数组中弹出种子来分配团队进行比赛): 1,2,3,4,5,6,7,8

需要将其分类为: 1,8,4,5,2,7,3,6

为了澄清这一点,在排序的数组中,较高的种子之间需要有最大的距离,这样在没有混乱的括号中,较低的种子首先被淘汰,而与较高种子的匹配则尽可能晚。实际上,想想网球比赛,在那里你想阻止16或32人等中排名前4的球员在半决赛前相互比赛。因此,16种子括号的正确阵列输出为:

1,16,8,9,4,13,5,12,2,15,7,10,3,14,6,11

这将转化为以下第一轮比赛:

v16 v9 v12 v12 v14 v11


多亏Matt Ball为8种子括号提供了正确的算法,这可能不如@alex使用自定义
排序
函数的答案有效,但肯定更容易编写和理解:

// This algorithm assumes that seeds.length is an even number
var seeds = [1, 2, 3, 4, 5, 6, 7, 8],
    firstRound = [];

while (seeds.length)
{
    firstRound.push(seeds.shift());
    firstRound.push(seeds.pop());
}

// seeds is now empty
// firstRound is now [1, 8, 2, 7, 3, 6, 4, 5]


事实上,我刚刚想到了一个更快的算法(就地“排序”,需要
O(n)
时间):

//还假定seeds.length是偶数
var seeds=[1,2,3,4,5,6,7,8],
numseds=seeds.length,
停止=numseds>>1,
临时雇员

对于(var i=1;i我提出了一个解决方案,但它超出了“排序数组”的范围

(javascript)代码位于

基本上,该算法假设括号中不会出现混乱,因此种子1和2应在最后一轮相遇。它在每一轮中迭代每个种子(从预先计算的总决赛开始,向后运行),计算前一轮中与当前种子匹配的未知种子(在迭代中)已获胜。这是可以做到的,因为给定一个种子和整数,您可以计算出另一个种子应该是什么:

其他种子=轮中的种子数+1-已知种子

举例来说,在半决赛中:

半决赛1(已知种子为1):其他种子=4+1-1=4

半决赛2(已知种子为2):其他种子=4+1-2=3

我只是在看我画的“无烦恼”括号时注意到了这个模式

在最终迭代(即第1轮)中,所有种子及其位置都已知,可以分配给匹配项。正确的排序数组如下:

1,16,8,9,4,13,5,12,2,15,7,10,3,14,6,11

再次感谢Matt Ball,他为小括号提出了正确的解决方案(在没有详细背景的情况下,很难陈述问题和期望的解决方案,而我在最初的问题中没有完全做到这一点)


如果有人有其他解决方案或我的解决方案的更优雅版本,请让我们知道!

从上到下匹配玩家的想法是正确的,但并不完全。在第一轮中,这样做非常有效:

while (seeds.length)
{
    firstRound.push(seeds.shift());
    firstRound.push(seeds.pop());
}
1, 2, 3, 4, 5, 6, 7, 8 => 1, 8, 2, 7, 3, 6, 4, 5
…但在第二轮中,种子1遇到种子2,种子3遇到种子4。我们需要为每轮进行第一/最后一次洗牌。第一次,我们分别移动每个元素。。第二次,我们移动每个元素对。。第三次,我们移动四个的组,以此类推,直到我们的组大小变小
种子。长度/2
。如下所示:

// this is ruby, aka javascript psuedo-code :)

bracket_list = seeds.clone

slice = 1
while slice < bracket_list.length/2
  temp = bracket_list
  bracket_list = []

  while temp.length > 0
    bracket_list.concat temp.slice!(0, slice)       # n from the beginning
    bracket_list.concat temp.slice!(-slice, slice)  # n from the end
  end

  slice *= 2
end
return bracket_list
现在,在倒数第8名球员被淘汰后,我们剩下的是
1,8,4,5,2,7,3,6
。倒数第4名球员被淘汰后,我们有
1,4,2,3
,在最后一轮中只有
1,2


如果不能画一个括号,很难解释这一点……如果我能为您澄清一些事情,请告诉我。

这是我开发的算法。步骤1是绘制一个表,表中的行数与团队数相同(四舍五入为2的幂)以及表示二进制中团队数量所需的任意多个列。例如,共有8个团队。表格最初将如下所示(点表示水平单元格边框):

。 | | | | . . . | | | | . . . | | | | . . . | | | | . . . | | | | . . . | | | | . . . | | | | . . . | | | |

列从左起按升序编号。对于每一列,在每2^(列编号)行处放置一个星号。即,第1列中每2行,第2列中每4行等

。 | | | | . . . | | | | * . . | | | | . . . | | | | * * . | | | | . . . | | | | * . . | | | | . . . ||||


在第一行的每列中以0开头。此后,对于每列中的连续行,除非该行中有星号,否则从0-1和1-0切换。这是结果:

。 |0|0|0| . . . |1|1|1| * . . |1|0|0| . . . |0|1|1| * * . |0|1|0| . . . |1|0|1| * . . |1|1|0| . . . |0 | 0 | 1|


最后一步是计算每一行,将0和1的字符串视为二进制数。这将产生0-7之间的值。向每一行添加1将产生1-8之间的值。这些值对应于种子

。 |0|0|0| + 1 = 1 . . . |1|1|1| + 1 = 8 * . . |1|0|0| + 1 = 5 . . . |0|1|1| + 1 = 4 * * . |0|1|0| + 1 = 3 . . . |1|0|1| + 1 = 6 * . . |1|1|0| + 1 = 7 . . . |0 | 0 | 1 |+1=2


每对种子是按顺序进行的比赛。即1-8、5-4、3-6和7-2。这可以扩展到任意数量的种子。当由于条目数小于2的幂而插入“是”时,它们采用最高的种子值。例如,如果只有28个条目,则“是”将占据分配给29、30、31和29的位置32.

我用PHP编写了一个解决方案(请参阅)。 这是javascript版本

它返回所有位于正确位置的种子
// this is ruby, aka javascript psuedo-code :)

bracket_list = seeds.clone

slice = 1
while slice < bracket_list.length/2
  temp = bracket_list
  bracket_list = []

  while temp.length > 0
    bracket_list.concat temp.slice!(0, slice)       # n from the beginning
    bracket_list.concat temp.slice!(-slice, slice)  # n from the end
  end

  slice *= 2
end
return bracket_list
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16

(1, 16),  (2, 15),  (3, 14),  (4, 13),   (5, 12),   (6, 11),   (7, 10),   (8, 9)

(1, 16, 8, 9),  (2, 15, 7, 10),  (3, 14, 6, 11),  (4, 13, 5, 12)

(1, 16, 8, 9, 4, 13, 5, 12),  (2, 15, 7, 10, 3, 14, 6, 11)
def seed(n)
  rounded_n = next_power_of_two(n)
  nbr_bits_required=rounded_n.to_s(2).length-1
  binary_seeds = Array.new(rounded_n) {Array.new(nbr_bits_required)}
  binary_seeds[0]=Array.new(nbr_bits_required){0}

  nbr_bits_required.times do |col|    
    1.upto(rounded_n-1) do |row|
      if row % (2**(col+1)) == 0
        #asterisk in the previous row, don't inverse the bit
        binary_seeds[row][col] = binary_seeds[row-1][col]
      else
        #no asterisk in the previous row, inverse the bit
        binary_seeds[row][col] = binary_seeds[row-1][col] == 0 ? 1 : 0
      end
    end
  end

  #output the result in decimal format
  binary_seeds.collect {|bs| s=(bs.join("")).to_i(2)+1; s>n ? -1 : s}
end

def next_power_of_two(n)
  k = 1
  k*=2 while k<n
  k
end
seed(8)
=> [1, 8, 5, 4, 3, 6, 7, 2]

seed(6)
=> [1, -1, 5, 4, 3, 6, -1, 2]