Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.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
Arrays 顺序排序_Arrays_Ruby_Sorting - Fatal编程技术网

Arrays 顺序排序

Arrays 顺序排序,arrays,ruby,sorting,Arrays,Ruby,Sorting,具有包含两个distincts元素的无序数组: arr = ["portrait", "landscape", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "l

具有包含两个distincts元素的无序数组:

arr = ["portrait", "landscape", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "landscape", "landscape"]
在此示例中,查看“排序”阵列,使其每四幅肖像中有一幅风景画:


如果不是一条直线,那么实现这一目标的最短途径是什么?

在不知道回退是什么意思的情况下,下面是如何实现您想要的目标的示例。这可能不是最优雅的解决方案,但很简单:

#!/usr/bin/env ruby

arr = (['P'] * 32 + ['L'] * 12).shuffle  # as an example
ps, ls = arr.partition { |element| element == 'P' }
result = []

loop do
    portrait_count = [4, ps.size].min
    portrait_count.times { result << ps.shift }

    landscape_count = [1, ls.size].min
    landscape_count.times { result << ls.shift }

    break if ps.empty? && ls.empty?
end

puts result.each_slice(5) { |slice| p slice }

=begin
Outputs:
["P", "P", "P", "P", "L"]
["P", "P", "P", "P", "L"]
["P", "P", "P", "P", "L"]
["P", "P", "P", "P", "L"]
["P", "P", "P", "P", "L"]
["P", "P", "P", "P", "L"]
["P", "P", "P", "P", "L"]
["P", "P", "P", "P", "L"]
["L", "L", "L", "L"]
=end

我假设每个对象不仅仅有一个“纵向”或“横向”开关,这就是为什么我将元素按顺序从数组中取出。

我猜如果纵向的数量与横向的数量不一致,那么它会将剩余的元素添加到一行中:

arr = %w[portrait landscape portrait portrait portrait portrait portrait portrait portrait portrait portrait portrait portrait portrait portrait portrait portrait portrait landscape landscape]
landscapes, portraits =  arr.sort.slice_when { |a, b| a != b }.to_a
p portraits.each_slice(4).flat_map.with_index { |e, i| e << landscapes[i] }.compact

# ["portrait", "portrait", "portrait", "portrait", "landscape", "portrait", "portrait", "portrait", "portrait", "landscape", "portrait", "portrait", "portrait", "portrait", "landscape", "portrait", "portrait", "portrait", "portrait", "portrait"]

这种方法强调计算效率。我计算数组中肖像的数量,并由此计算四人一组的数量以及剩余肖像和风景的数量。然后,我使用这三个量来构造所需的数组,这不需要任何迭代步骤

代码

例子

解释

对于上述arr,步骤如下所示

nbr_portraits = arr.count("portrait")
  #=> 17
nbr_landscapes = arr.size - nbr_portraits
  #=> 3
groups_of_4_portraits = [nbr_portraits/4, nbr_landscapes].min
  #=> 3
nbr_portraits -= 4 * groups_of_4_portraits
  #=> 5
nbr_landscapes -= groups_of_4_portraits
  #=> 0
b = ["portrait"] * 4
  #=> ["portrait", "portrait", "portrait", "portrait"]
c = [*b, "landscape"]
  #=> ["portrait", "portrait", "portrait", "portrait", "landscape"]
d = c * groups_of_4_portraits
  #=> ["portrait", "portrait", "portrait", "portrait", "landscape",
  #    "portrait", "portrait", "portrait", "portrait", "landscape",
  #    "portrait", "portrait", "portrait", "portrait", "landscape"]
e = ["portrait"] * nbr_portraits
  #=> ["portrait", "portrait", "portrait", "portrait", "portrait"]
f = ["landscape"] * nbr_landscapes
  #=> []
[*d, *e, *f]
  #=> ["portrait", "portrait", "portrait", "portrait", "landscape",
  #    "portrait", "portrait", "portrait", "portrait", "landscape",
  #    "portrait", "portrait", "portrait", "portrait", "landscape",
  #    "portrait", "portrait", "portrait", "portrait", "portrait"]   
快速基准

这里我将上述方法与Sebastian和Keith的解决方案进行比较。结果无法直接比较,因为我们对这个问题的理解不同。基思和我把剩下的肖像画或风景画放在头像的末尾,而塞巴斯蒂安只把剩下的肖像画放在末尾,丢弃了剩下的风景画

require 'fruity'

np = 100
nl = 120

p (arr = [*["portrait"]*np, *["landscape"]*nl].shuffle).size

def sebastian(arr)
  landscapes, portraits =  arr.sort.slice_when { |a, b| a != b }.to_a
  portraits.each_slice(4).flat_map.with_index { |e, i| e << landscapes[i] }.compact
end

def keith(arr)
  ps, ls = arr.partition { |element| element == 'portrait' }
  result = []    
  loop do
    portrait_count = [4, ps.size].min
    portrait_count.times { result << ps.shift }
    landscape_count = [1, ls.size].min
    landscape_count.times { result << ls.shift }
    break if ps.empty? && ls.empty?
  end
  result
end

compare(
  Sebastian: -> { sebastian arr },
  Keith:     -> { keith arr },
  Cary:      -> { rearrange arr }
)

Running each test 64 times. Test will take about 1 second.
Cary is faster than Keith by 5x ± 1.0
Keith is similar to Sebastian

缺少一幅肖像,您的预期输出是什么,需要涵盖哪些场景?您可以收集风景和肖像条目的总数,而不是对阵列进行排序,并创建一个新阵列,其中元素位于正确的位置。这使您能够轻松处理没有足够的可用环境的情况,并使您能够轻松控制输出顺序。好的,退步是什么?Keith,我把你的解决方案添加到了基准测试中。我不知道我怎么会错过它。
arr = ["portrait", "landscape", "portrait", "portrait", "portrait", "portrait",
       "portrait", "portrait", "portrait", "portrait", "portrait", "portrait",
       "portrait", "portrait", "portrait", "portrait", "portrait", "portrait",
      "landscape", "landscape"]

rearrange arr
  #=> ["portrait", "portrait", "portrait", "portrait", "landscape",
  #    "portrait", "portrait", "portrait", "portrait", "landscape",
  #    "portrait", "portrait", "portrait", "portrait", "landscape",
  #    "portrait", "portrait", "portrait", "portrait", "portrait"]   

rearrange %w| portrait portrait portrait landscape portrait portrait
              portrait portrait portrait portrait |
  #=> ["portrait", "portrait", "portrait", "portrait", "landscape",
  #    "portrait", "portrait", "portrait", "portrait", "portrait"]

rearrange %w| portrait portrait portrait portrait portrait |
  #=> ["portrait", "portrait", "portrait", "portrait", "portrait"]

rearrange %w| landscape landscape portrait landscape portrait |
  #=> ["portrait", "portrait", "landscape", "landscape", "landscape"]

rearrange %w| landscape landscape landscape landscape |
  #=> ["landscape", "landscape", "landscape", "landscape"]

rearrange []
  #=> []
nbr_portraits = arr.count("portrait")
  #=> 17
nbr_landscapes = arr.size - nbr_portraits
  #=> 3
groups_of_4_portraits = [nbr_portraits/4, nbr_landscapes].min
  #=> 3
nbr_portraits -= 4 * groups_of_4_portraits
  #=> 5
nbr_landscapes -= groups_of_4_portraits
  #=> 0
b = ["portrait"] * 4
  #=> ["portrait", "portrait", "portrait", "portrait"]
c = [*b, "landscape"]
  #=> ["portrait", "portrait", "portrait", "portrait", "landscape"]
d = c * groups_of_4_portraits
  #=> ["portrait", "portrait", "portrait", "portrait", "landscape",
  #    "portrait", "portrait", "portrait", "portrait", "landscape",
  #    "portrait", "portrait", "portrait", "portrait", "landscape"]
e = ["portrait"] * nbr_portraits
  #=> ["portrait", "portrait", "portrait", "portrait", "portrait"]
f = ["landscape"] * nbr_landscapes
  #=> []
[*d, *e, *f]
  #=> ["portrait", "portrait", "portrait", "portrait", "landscape",
  #    "portrait", "portrait", "portrait", "portrait", "landscape",
  #    "portrait", "portrait", "portrait", "portrait", "landscape",
  #    "portrait", "portrait", "portrait", "portrait", "portrait"]   
require 'fruity'

np = 100
nl = 120

p (arr = [*["portrait"]*np, *["landscape"]*nl].shuffle).size

def sebastian(arr)
  landscapes, portraits =  arr.sort.slice_when { |a, b| a != b }.to_a
  portraits.each_slice(4).flat_map.with_index { |e, i| e << landscapes[i] }.compact
end

def keith(arr)
  ps, ls = arr.partition { |element| element == 'portrait' }
  result = []    
  loop do
    portrait_count = [4, ps.size].min
    portrait_count.times { result << ps.shift }
    landscape_count = [1, ls.size].min
    landscape_count.times { result << ls.shift }
    break if ps.empty? && ls.empty?
  end
  result
end

compare(
  Sebastian: -> { sebastian arr },
  Keith:     -> { keith arr },
  Cary:      -> { rearrange arr }
)

Running each test 64 times. Test will take about 1 second.
Cary is faster than Keith by 5x ± 1.0
Keith is similar to Sebastian