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"]