Arrays /code>是s1的超集,当且仅当s1是s2的子集
请注意,Arrays /code>是s1的超集,当且仅当s1是s2的子集,arrays,ruby,algorithm,Arrays,Ruby,Algorithm,请注意,s1是s2的子集,s1.size true` “cat”不是“颁布”的子集,因为m(0)=3和m(1)=2,但m(0)
s1
是s2
的子集,s1.size true`
“cat”不是“颁布”的子集,因为m(0)=3
和m(1)=2
,但m(0)
为假李>
算法
子集(也就是超集)是一种传递关系,允许显著的算法效率。我的意思是,如果s1
是s2
的子集,s2
是s3
的子集,那么s1
是s3
的子集
我会进行以下工作:
- 创建空集合
既不包含子集合也不包含子集合
和最长集合
以及空数组子集合和子集合
- 把字典里的单词按长度排序,最长的排在第一位
- 将
w
添加到中,其中w
是词典中最长的单词
- 对于字典中的每个后续单词
w
(从最长到最短),执行以下操作:
- 对于
的每个元素u
,不确定w
是否是u
的子集。如果是,则将u
从既不分又不分
移动到最长
并将u
附加到子和子
- 如果将一个或多个元素从
none_sub_,not_sup
移动到longest_sups
,则将w
附加到subs_和_sups
;否则将w
添加到中,既不添加sub也不添加sup
- 返回
subs\u和sups
代码
require 'set'
def identify_subs_and_sups(dict)
neither_sub_nor_sup, longest_sups = Set.new, Set.new
dict.sort_by(&:size).reverse.each_with_object([]) do |w,subs_and_sups|
switchers = neither_sub_nor_sup.each_with_object([]) { |u,arr|
arr << u if w.subset(u) }
if switchers.any?
subs_and_sups << w
switchers.each do |u|
neither_sub_nor_sup.delete(u)
longest_sups << u
subs_and_sups << u
end
else
neither_sub_nor_sup << w
end
end
end
class String
def subset(w)
w =~ Regexp.new(self.gsub(/./) { |m| "#{m}\\w*" })
end
end
dict = %w| cat catch craft cutie enact trivial rivert river |
#=> ["cat", "catch", "craft", "cutie", "enact", "trivial", "rivert", "river"]
identify_subs_and_sups(dict)
#=> ["river", "rivert", "cat", "catch", "craft"]
变体
与其将字典中的单词从最长到最短进行处理,不如将它们从最短到最长进行排序:
def identify_subs_and_sups1(dict)
neither_sub_nor_sup, shortest_sups = Set.new, Set.new
dict.sort_by(&:size).each_with_object([]) do |w,subs_and_sups|
switchers = neither_sub_nor_sup.each_with_object([]) { |u,arr|
arr << u if u.subset(w) }
if switchers.any?
subs_and_sups << w
switchers.each do |u|
neither_sub_nor_sup.delete(u)
shortest_sups << u
subs_and_sups << u
end
else
neither_sub_nor_sup << w
end
end
end
identify_subs_and_sups1(dict)
#=> ["craft", "cat", "rivert", "river"]
def识别SUB和sups1(dict)
既不包含子项也不包含子项,最短项=Set.new,Set.new
dict.sort_by(&:size)。每个带有_对象([])的_都执行w、subs和sups|
切换器=既不包含子对象也不包含子对象([]){u,arr|
arr除了每个单词生成一组不需要再检查的子集和超集之外,我想通过从集合中删除它们的内容来最小化不必要的循环。我会使用第二种方法(使用集而不是数组),然后测试集合中的成员资格,看看是否应该跳过当前单词。同样,如果@seph演示的那样,您可以使用delete\u删除当前值,但除了迭代过程中没有迭代器支持删除之外,您将跳过不打算跳过的内容。除了每个单词生成一组子元素之外不需要再检查的集合和超集,我希望通过从集合中删除它们的内容来最小化不必要的循环。我将使用第二种方法(使用集合而不是数组),然后测试集合中的成员身份,看看是否应该跳过当前单词。同样,如果@seph演示的那样,您可以使用delete\u删除当前值,但除了迭代过程中没有迭代器支持删除之外,您将跳过不打算跳过的内容。超集和子集的减法
发生得太晚了,也就是说,它需要在find
方法命中这些集合之前发生。如果“超级计算机”是“sprout”的超集单词,那么选中“sprout”意味着我不必选中“超级计算机”。对超集和子集的减法发生得太晚,即需要在find
方法命中这些集合之前进行。如果“supercomputer”是“sprout”的超集,那么选中“sprout”意味着我不必选中“supercomputer”。谢谢你的编辑建议。在你离开建议的编辑之前或之后,我注意到并编辑了未完成的句子。旁白:去熊!('65).大多数作曲家都擅长数学,这是真的吗?你现在认为自己是一个Ruby作曲家吗?谢谢你的回答,这将大大有助于我的算法设计。我不知道作曲家是否有数学天赋,是的,我对“作曲家”的定义在过去几年中有了很大的扩展。很高兴见到你认识你,@CarySwoveland!谢谢你的编辑建议。在你离开建议的编辑之前或之后,我注意到并编辑了未完成的句子。旁白:去熊!('65).大多数作曲家都擅长数学,这是真的吗?你现在认为自己是一个Ruby作曲家吗?谢谢你的回答,这将大大有助于我的算法设计。我不知道作曲家是否有数学天赋,是的,我对“作曲家”的定义在过去几年中有了很大的扩展。很高兴见到你我开始用最短的词,消除超集,而不是绕过B/C发现超集是一个更便宜的例程。当我重构代码时,我肯定会考虑在哈希上创建例程,并创建.子集和.SuffSt.方法。如果你编辑添加一个字典,我会的。运行一个基准测试。下面是一个细节,我(可能是错误的)思想是不相关的,即“子集”的精确定义:它基本上是你建议的,但不包括严格的子字符串,即cat
是craft
的子集,而不是catalog
——而catalog
是clog
的超集。对于正则表达式,“我是什么的子字符串?”回答“我是什么超弦的?”要比回答“我是什么超弦的?”快得多。然而,“我是什么超弦的超弦/超弦的吗?”可能会有很大的不同。如果你在Mac上,你可以用“/usr/share/dict/words”来运行它。谢谢。今天晚些时候,我将使用该文件(Mac上的是)来运行基准测试:我的代码,我的代码最短单词f
require 'set'
def identify_subs_and_sups(dict)
neither_sub_nor_sup, longest_sups = Set.new, Set.new
dict.sort_by(&:size).reverse.each_with_object([]) do |w,subs_and_sups|
switchers = neither_sub_nor_sup.each_with_object([]) { |u,arr|
arr << u if w.subset(u) }
if switchers.any?
subs_and_sups << w
switchers.each do |u|
neither_sub_nor_sup.delete(u)
longest_sups << u
subs_and_sups << u
end
else
neither_sub_nor_sup << w
end
end
end
class String
def subset(w)
w =~ Regexp.new(self.gsub(/./) { |m| "#{m}\\w*" })
end
end
dict = %w| cat catch craft cutie enact trivial rivert river |
#=> ["cat", "catch", "craft", "cutie", "enact", "trivial", "rivert", "river"]
identify_subs_and_sups(dict)
#=> ["river", "rivert", "cat", "catch", "craft"]
def identify_subs_and_sups1(dict)
neither_sub_nor_sup, shortest_sups = Set.new, Set.new
dict.sort_by(&:size).each_with_object([]) do |w,subs_and_sups|
switchers = neither_sub_nor_sup.each_with_object([]) { |u,arr|
arr << u if u.subset(w) }
if switchers.any?
subs_and_sups << w
switchers.each do |u|
neither_sub_nor_sup.delete(u)
shortest_sups << u
subs_and_sups << u
end
else
neither_sub_nor_sup << w
end
end
end
identify_subs_and_sups1(dict)
#=> ["craft", "cat", "rivert", "river"]