给定元素(或索引)周围的子阵列

时间:2014-11-13 10:46:51

标签: ruby algorithm arrays

在该数组中给定一个最多24个唯一元素和一个特定元素(或索引)的数组,如何找到由该索引“周围”元素组成的最多12个元素的子数组?

我周围的意思是,如果索引之前和之后有足够的元素,它应该在子数组的中间。如果之前元素太少,则应在索引之后更多地获取12个元素的目标,即使索引不在所得子阵列的中间。

我无法解决这个看似简单的问题。

我已经解决了一些琐碎的案例,但我找不到通用的解决方案......

if array.length <= 12整个数组就是解决方案

当数组由恰好24个元素(可能不是)组成,并且索引在6到18之间时,子数组为array[index - 6, 12]

如果索引为0,则子阵列为array[0, min(12, array.length)]

我正在使用红宝石,但可以随意使用您选择的任何语言:)

澄清一些例子:

# Wanted element in the middle:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]
                                  #^^

# Expected result:

[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
                   #^^

# Wanted element in the middle:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]
                                  #^^

# Expected result:

[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
                   #^^

# Wanted element is early:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]
      #^

# Expected result:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
      #^

# Wanted element is late:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]
                                                                      #^^

# Expected result:

[ 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]
                                 #^^

# Less elements:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
                                  #^^

# Expected result:

[3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
                         #^^

你能帮助我吗?

由于

2 个答案:

答案 0 :(得分:1)

Ruby数组支持arr.drop(n)arr.take(n)删除初始元素并获取后续元素,因此当数组长度大于12时,只需删除(length-12)/ 2然后取12个元素。

注意:您可能需要考虑数组有13个元素的情况,答案是前12个字符还是后12个字符?

arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
arr.drop((arr.length-12)/2).take(12)

以上工作用于查找15个数组中间的12个元素,为了概括这一点,您需要考虑一种方法来计算在给定随机索引时取出12个元素之前要删除的元素数量。

很难更具体,因为我不能100%确定你想要的是什么,一些实际的例子会有所帮助。

修改问题后更新:

看起来你需要做的就是在psuedo代码中找出你想要的元素范围:

idx = <The index of the element to select around>
startIdx = idx - 6 ;
endIdx   = idx + 5 ;

if startIdx < 0 then take the 1st 12 elements
else if endIdx > arr.length then
   drop arr.length - 12 elements
else
   drop startIdx elements
   take 12 elements

答案 1 :(得分:1)

这是一种方法。

<强>代码

def sub(arr, target_ndx, max_size, bias = :LEFT)
  arr_size = arr.size 
  return arr if arr_size <= max_size

  diff = arr_size - max_size
  left = diff/2 - 1
  left += 1 if diff.even? && bias == :RIGHT
  right = left + max_size-1

  return arr[left, max_size] if (left..right).cover?(target_ndx)

  left = target_ndx+1-(max_size+1)/2
  left -= 1 if max_size.even? && bias==:RIGHT
  left = [left, 0].max
  left = [left, arr_size-max_size].min
  arr[left, max_size]
end

<强>实施例

sub([*0..23], 11, 12)         # mid
  #=> [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
sub([*0..23], 11, 12, :RIGHT) # mid
  #=> [6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]
sub([*0..23], 2, 12)          # early
  #=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
sub([*0..23], 20, 12)         # late
  #=> [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]
sub([*0..14], 11, 12)         # fewer
  #=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
sub([*0..23], 7, 3)
  #=> [6, 7, 8]
sub([*0..23], 17, 3)
  #=> [16, 17, 18]
sub([*0..23], 6, 4)
  #=> [5, 6, 7, 8]
sub([*0..23], 6, 4, :RIGHT)
  #=> [4, 5, 6, 7]