我有两个阵列;其中一个b
可能是另一个的一部分,a
;如何检查b
是否为a
基本上,[3, 4, 5]
将是(1..10).to_a
的子序列,但不是(1..10).to_a.shuffle
。
答案 0 :(得分:3)
a = [1,2,3]
b = (1..10).to_a
a_sorted = a.sort
b.each_cons(a.size).any?{ |c| c.sort == a_sorted }
原始解决方案
b.each_cons(a.size).any?{ |c| c == a }
答案 1 :(得分:2)
使用Enumerable连续迭代
arr = [1,2,3]
(1..10).to_a.each_cons(arr.size).include? arr
# => true
arr = [1,3,2]
(1..10).to_a.each_cons(arr.size).include? arr
# => false
答案 2 :(得分:1)
您可以对潜在子集的每个元素使用Enumerable的#find_index
方法,并确保索引在潜在超集中的顺序相同。
试试这个:
a = (1..10).to_a
b = [3,4,5]
# Use #compact to remove all nils
b_indices = b.map {|x| a.find_index(x)}.compact
b_indices == b_indices.sort # use #sort to ensure ordering
答案 3 :(得分:0)
您可以使用Set
或Array
的默认方法。
Array
看看它:
How can I get the intersection, union, and subset of arrays in Ruby?
Set
:http://www.ruby-doc.org/stdlib-2.1.2/libdoc/set/rdoc/Set.html
答案 4 :(得分:0)
也许不是最优雅的解决方案,但应该可以肯定。 简单的蛮力:
def substring?(a, b)
position = 0
a.each_with_index do |v, i|
if v == b[position] and (i + b.size - position) <= a.size
position += 1
elsif position == b.size
return true
else
position = 0
end
end
position == b.size
end
其中 b 是您的数组, a 是候选子集。
答案 5 :(得分:0)
这是另一种方式。这个解决方案符合我对问题的理解,但它可能不是提问者的想法。看看我对这个问题的评论。 (编辑:在澄清问题时,这不是提问者想要的,但我会留下它可能的教育价值。)
<强>代码强>
def subsequence?(a,b)
c = b.map.with_index.to_h.values_at(*a)
return false if c.any?(&:nil?)
c == c.sort
end
<强>实施例强>
subsequence?([3,4,5], (1..10).to_a) #=> true
subsequence?([3,5,4], (1..10).to_a) #=> false
subsequence?([3,4,5], (1..10).to_a.reverse) #=> false
subsequence?([3,4,5], [1,2,3,4,6]) #=> false
subsequence?([3,4,5], [3,4,2,5]) #=> true
<强>解释强>
计算后
c = b.map.with_index.to_h.values_at(*a)
c.any?(&:nil?)
确定b
是否包含a
的所有元素。如果是的话
c == c.sort
检查它们是否处于相同的顺序。
示例1
a = [3,4,5]
b = (1..10).to_a
然后
d = b.map.with_index.to_h
#=> {1=>0, 2=>1, 3=>2, 4=>3, 5=>4, 6=>5, 7=>6, 8=>7, 9=>8, 10=>9}
c = d.values_at(*a)
#=> [2, 3, 4]
c.any?(&:nil?)
#=> false
因此,我们看到a
中包含b
的值,我们需要查看它们是否按顺序排列:
c == c.sort
#=> [2, 3, 4] == [2, 3, 4]
#=> true
示例2
a = [3,5,4]
b = (1..10).to_a
然后
d = b.map.with_index.to_h
#=> {1=>0, 2=>1, 3=>2, 4=>3, 5=>4, 6=>5, 7=>6, 8=>7, 9=>8, 10=>9}
c = d.values_at(*a)
#=> [2, 4, 3]
c.any?(&:nil?)
#=> false
所以我们再次需要看看它们是否有序:
c == c.sort
#=> [2, 4, 3] == [2, 3, 4]
#=> false
示例3
a = [3,5,4]
b = (1..10).to_a.reverse
然后
d = b.map.with_index.to_h
#=> {10=>0, 9=>1, 8=>2, 7=>3, 6=>4, 5=>5, 4=>6, 3=>7, 2=>8, 1=>9}
c = d.values_at(*a)
#=> [7, 5, 6]
c.any?(&:nil?)
#=> true
c == c.sort
#=> false
示例4
a = [3,5,4]
b = [1,2,3,4,6]
然后
d = b.map.with_index.to_h
#=> {1=>0, 2=>1, 3=>2, 4=>3, 6=>4}
c = d.values_at(*a)
#=> [2, nil, 3]
c.any?(&:nil?)
#=> true
示例5
a = [3,4,5]
b = [3,4,2,5]
然后
d = b.map.with_index.to_h
#=> {3=>0, 4=>1, 2=>2, 5=>3}
c = d.values_at(*a)
#=> [0, 1, 3]
c.any?(&:nil?)
#=> false
c == c.sort
#=> true
又一个解决方案
def subsequence?(a,b)
([a] & b.combination(a.size).to_a).any?
end
答案 6 :(得分:0)
还有一个。这个解决方案符合我对问题的理解,但它可能不是提问者的想法。看看我对这个问题的评论。 (编辑:在澄清问题时,这不是提问者想要的,但我会留下它可能的教育价值。)
<强>代码强>
def subsequence?(a,b)
enum_a = a.each
enum_b = b.each
loop do
av = enum_a.next
loop do
begin
bv = enum_b.next
break if (av == bv)
rescue StopIteration
return false
end
end
end
true
end
<强>实施例强>
subsequence?([3,4,5], (1..10).to_a) #=> true
subsequence?([3,5,4], (1..10).to_a) #=> false
subsequence?([3,4,5], (1..10).to_a.reverse) #=> false
subsequence?([3,4,5], (1..10).to_a.reverse) #=> false
subsequence?([3,4,5], [1,2,3,4,6]) #=> false
subsequence?([3,4,5], [3,4,2,5]) #=> true
答案 7 :(得分:0)
非常简单有效的方法(不是零安全):
leftovers = array.reduce(sub) { |a, e| e == a[0] ? a[1..-1] : a }
puts "sub is subsequence of array!" if leftovers.empty?
请参阅:https://ruby-doc.org/core-2.2.0/Enumerable.html#method-i-reduce