Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.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
在Ruby中提取两个数字之间的项_Ruby_Algorithm - Fatal编程技术网

在Ruby中提取两个数字之间的项

在Ruby中提取两个数字之间的项,ruby,algorithm,Ruby,Algorithm,问题: 给定Ruby中的数字数组,返回出现在1和2之间的数字组 数字1和2不会出现在其他1和2之间(不存在子集的子集) 示例1 输入:[1,3,2,1,4,2] 输出:[[1,3,2],[1,4,2]] 示例2 输入:[0,1,3,2,10,1,5,6,7,8,7,5,2,3,1,-400,2,12,16] 输出:[[1,3,2],[1,5,6,7,8,7,5,2],[1,-400,2]] 我的直觉是使用#chunk和#drop_的组合,而或生成器 提前谢谢。听起来像是一个面试问题。我将解释

问题:

  • 给定Ruby中的数字数组,返回出现在1和2之间的数字组
  • 数字1和2不会出现在其他1和2之间(不存在子集的子集)
示例1

输入:
[1,3,2,1,4,2]

输出:
[[1,3,2],[1,4,2]]

示例2

输入:[0,1,3,2,10,1,5,6,7,8,7,5,2,3,1,-400,2,12,16]

输出:[[1,3,2],[1,5,6,7,8,7,5,2],[1,-400,2]]

我的直觉是使用
#chunk
#drop_的组合,而
或生成器


提前谢谢。

听起来像是一个面试问题。我将解释我能想到的最简单的算法:

在数组中循环一次,并在运行时生成输出。当您遇到
1
时,您将其和随后的数字存储到另一个临时数组中。当遇到
2
时,将数组放入输出数组中。边缘情况包括:

  • 另一个
    1
    在您开始构建临时阵列之后
  • 如果没有临时数组,则为
    2
第一种情况很简单,当遇到
1
时,请始终构建一个新的临时数组。对于第二个,您必须检查临时数组中是否有任何项,如果临时数组不是空的,则只将临时数组附加到输出中

这应该可以让你开始了。

你可以使用和Ruby的操作符:

input = [0, 1, 3, 2, 10, 1, 5, 6, 7, 8, 7, 5, 2, 3, 1, -400, 2, 12, 16]

input.chunk { |i| true if i==1..i==2 }.each { |_, ary| p ary }
输出:

[1, 3, 2]
[1, 5, 6, 7, 8, 7, 5, 2]
[1, -400, 2]

由于您评论并添加了您实际上正在阅读一个文件,我删除了我的旧答案(正如@Stefan所指出的,这个答案无论如何都是错误的),然后用这个来补充。您可以将其粘贴到一个文件中并运行它,
数据
IO包含
\uuuuu END\uuuu
之后显示的所有内容。在应用程序中,您可以将其替换为您的文件

类Chunker
开始指示灯=“开始”
END_INDICATOR=“END”
def初始化(io)
@io=io
结束
定义每个
返回(:每个)的枚举u如果!给你块钱?
chunk=nil
虽然io.eof?做
line=io.readline.chomp
如果行==开始指示器
区块=[]

chunk适用于所有想在海滩上散步的人,但由于明显的原因不能:

class Flipflop

  def initialize(flip, flop) #flip and flop being boolean-returning lambdas
    @state = false
    @flip  = flip
    @flop  = flop
  end

  def flipflop(x) #logic taken from The Ruby Programming Language page 111
    if !@state
      result = @flip[x]
      if result
        @state = !@flop[x]
      end
      result
    else
      @state = !@flop[x]
      true
    end
  end

end

ff = Flipflop.new( ->(x){x == 1}, ->(x){x == 2} )
input = [0, 1, 3, 2, 10, 1, 5, 6, 7, 8, 7, 5, 2, 3, 1, -400, 2, 12, 16]

res = input.select{|el| ff.flipflop(el) }.slice_before(1) #an Enumerator
p res.to_a
# =>[[1, 3, 2], [1, 5, 6, 7, 8, 7, 5, 2], [1, -400, 2]]

对于字符串,
ff=Flipflop.new(->(x){x.chomp==“BEGIN”},->(x){x.chomp==“END”})
或类似的东西应该可以使用。

这是一个使用[Enumerable#slice_when][1]的选项:

ary1 = [1, 3, 2, 1, 4, 2]
ary2 = [0, 1, 3, 2, 10, 1, 5, 6, 7, 8, 7, 5, 2, 3, 1, -400, 2, 12, 16]
例如:

stop = [1, 2]
ary2.slice_when{ |e| stop.include? e }
    .each_slice(2).map { |a, b| b.unshift(a.last) if b }
    .reject { |e| e.nil? || (e.intersection stop).empty? }

#=> [[1, 3, 2], [1, 5, 6, 7, 8, 7, 5, 2], [1, -400, 2]]

其他选项

更详细但更清晰,考虑到输入:

input =  %w(b a b c a b c a c b c a c a)
start = 'a'
stop  = 'b'
使用
可枚举的#每个_和_对象
,如果使用其他
,为什么不使用好的旧

tmp = []
pickup = false
input.each_with_object([]) do |e, res|
  if e == start
    pickup = true
    tmp << e
  elsif pickup && e == stop
    tmp << e
    res << tmp
    tmp = []
    pickup = false
  elsif pickup
    tmp << e
  end
end

#=> [["a", "b"], ["a", "b"], ["a", "c", "b"]]

  [1]: https://ruby-doc.org/core-2.7.0/Enumerable.html#method-i-slice_when
tmp=[]
拾取=错误
输入。每个带有_对象([])的| e,res|
如果e==开始
皮卡=真

这听起来像是家庭作业。到目前为止你试过什么?展示你的代码。嗨,这不是为了学术目的。我有一个4 GB的日志文件,其中的行由我需要提取出来的单词
BEGIN
END
包围。这是我的第一次尝试。我更喜欢使用惰性枚举的解决方案。谢谢你。这个问题不是程序面试的问题。我同时喜欢和不喜欢这个解决方案。因为人字拖:-)@Pascal是的,人字拖很奇怪。但令人惊讶的是,很难找到一个几乎同样简洁的替代品。