在字符串数组中查找公共字符串(ruby)

在字符串数组中查找公共字符串(ruby),ruby,Ruby,假设我有一个由3个字符串组成的数组: ["Extra tv in bedroom", "Extra tv in living room", "Extra tv outside the shop"] 如何找到所有字符串共有的最长字符串 解释了可用于解决该问题的两种算法。如果要搜索所有字符串的开头: 来源 试验 输出 这里有一个红色的方法。如果有一堆字符串或字符串很长,则应使用更高级的算法,不过: def longest_common_substr(strings) shortest =

假设我有一个由3个字符串组成的数组:

["Extra tv in bedroom",
 "Extra tv in living room",
 "Extra tv outside the shop"]

如何找到所有字符串共有的最长字符串

解释了可用于解决该问题的两种算法。

如果要搜索所有字符串的开头:

来源 试验 输出
这里有一个红色的方法。如果有一堆字符串或字符串很长,则应使用更高级的算法,不过:

def longest_common_substr(strings)
  shortest = strings.min_by &:length
  maxlen = shortest.length
  maxlen.downto(0) do |len|
    0.upto(maxlen - len) do |start|
      substr = shortest[start,len]
      return substr if strings.all?{|str| str.include? substr }
    end
  end
end

puts longest_common_substr(["Extra tv in bedroom",
                            "Extra tv in living room",
                            "Extra tv outside the shop"])

不要认为这个比例特别好

def longest_substr(text)
    if (text.length == 0)
        return ""
    elseIf (text.length == 1)
        return text[0]
    end
    longest = text.inject(text[0].length) {|min, s| min < s.length ? min : s.length}
    (1 .. longest).to_a.reverse.each do |l|
        (0 .. text[0].length - l).each do |offset|
            str = text[0].slice(offset, l)
            matched = (1 .. text.length - 1).inject(true) {|matched, i| matched && text[i].index(str) != nil}
            if (matched)
                return str
            end
        end
    end

    return ""
end

puts longest_substr(["Alice's Extra tv in bedroom",
    "Bob's Extra tv in living room",
    "My Extra tv outside the shop"])
def longest_substr(文本)
如果(text.length==0)
返回“”
elseIf(text.length==1)
返回文本[0]
结束
longest=text.inject(text[0].length){| min,s | min
也仅用于字符串的开头

def longest_subsequence array
  array.sort!
  first = array[0].split(//)
  last = array[-1].split(//)
  length = (first.size > last.size) ? last.size : first.size
  sequence = ""
  index = 0
  while (first[index] == last[index]) && (index < length)
    sequence << first[index]
    index += 1
  end
  sequence
end
def最长的子序列数组
数组,排序!
first=数组[0]。拆分(//)
last=数组[-1]。拆分(/)
长度=(first.size>last.size)?最后一码:第一码
sequence=“”
索引=0
while(第一个[索引]==最后一个[索引]&&(索引<长度)

sequence不知道响应是否仍然有用,但这里有一个受@mckeed和@lins314159代码启发的解决方案

def longest_common_substr(strings)
    longest_substring = strings.map{|s| s.split}.max_by &:length
    longest_substring.inject do |target_str, token|
        r = Regexp.new("^#{target_str.nil? ? token : "#{target_str} #{token}".strip}")
        target_str = "#{target_str} #{token}".strip if strings.all? {|string| string =~ r}
        target_str
    end
end

puts longest_common_substr(["Extra tv and mat in bedroom",
                            "Extra tv and chair with view in living room",
                            "Extra tv and carpet outside the shop"])

你的意思是“任何”子字符串,还是应该只从一开始就进行比较?这里还有一个问题:@St.Woland:实际上,这取决于。对于我的例子,结果是一样的。但我问这个问题的原因实际上是因为我想知道我能做些什么来为任何给定的字符串数组找到“公共分母”的形式。@glenn:最长公共子序列是不同的,因为它不必是连续的。这篇wiki文章给出了两个字符串的完整解决方案:
def longest_substr(text)
    if (text.length == 0)
        return ""
    elseIf (text.length == 1)
        return text[0]
    end
    longest = text.inject(text[0].length) {|min, s| min < s.length ? min : s.length}
    (1 .. longest).to_a.reverse.each do |l|
        (0 .. text[0].length - l).each do |offset|
            str = text[0].slice(offset, l)
            matched = (1 .. text.length - 1).inject(true) {|matched, i| matched && text[i].index(str) != nil}
            if (matched)
                return str
            end
        end
    end

    return ""
end

puts longest_substr(["Alice's Extra tv in bedroom",
    "Bob's Extra tv in living room",
    "My Extra tv outside the shop"])
def longest_subsequence array
  array.sort!
  first = array[0].split(//)
  last = array[-1].split(//)
  length = (first.size > last.size) ? last.size : first.size
  sequence = ""
  index = 0
  while (first[index] == last[index]) && (index < length)
    sequence << first[index]
    index += 1
  end
  sequence
end
def longest_common_substr(strings)
    longest_substring = strings.map{|s| s.split}.max_by &:length
    longest_substring.inject do |target_str, token|
        r = Regexp.new("^#{target_str.nil? ? token : "#{target_str} #{token}".strip}")
        target_str = "#{target_str} #{token}".strip if strings.all? {|string| string =~ r}
        target_str
    end
end

puts longest_common_substr(["Extra tv and mat in bedroom",
                            "Extra tv and chair with view in living room",
                            "Extra tv and carpet outside the shop"])