Нахождение общей строки в массиве строк (рубин)

Учитывая у меня есть массив 3 строк:

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

Как я нахожу самую длинную строку, которую имеют общего все строки?

6
задан Jesper Rønn-Jensen 28 January 2010 в 22:03
поделиться

6 ответов

Вот рубинский способ сделать это. Вы должны использовать более продвинутый алгоритм, если у вас есть куча строк или они очень длинные, хотя:

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"])
17
ответ дан 8 December 2019 в 05:55
поделиться

Если вы хотите найти начало всех строк:

Source

def substr( a )
    return "" unless (a.length > 0)
    result = 0
    (0 ... a.first.length).each do |k|
        all_matched = true
        character = a.first[k]
        a.each{ |str| all_matched &= (character == str[k]) }
        break unless all_matched
        result+=1
    end
    a.first.slice(0,result)
end

Test

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

puts substr( input ) + "."

Output

Extra tv .
2
ответ дан 8 December 2019 в 05:55
поделиться

И еще один, если вы создаете таблицу с вложенной таблицей, вы получаете индекс, созданный автоматически. Объектное хранилище в целом может сделать это, поскольку созданы скрытые таблицы.

Я думаю, что Xmltypes на основе схемы также сделает это.

-121--2132426-

Эта статья Википедии объясняет два алгоритма, которые могут быть использованы для решения этой проблемы.

2
ответ дан 8 December 2019 в 05:55
поделиться

Не думайте, что это масштабы особенно хорошо.

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"])
0
ответ дан 8 December 2019 в 05:55
поделиться

Нет, это не сработает, на вашей странице будет определена только вторая функция. Здесь является источником.

-121--2132494-

Нет вы не можете сделать это... если вы не находитесь в состоянии «Нормально», для вас необходимо только последнее определение.

-121--2132496-

Также только для начала последовательностей.

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

Но я думаю, что должен быть способ легко сравнить начало только двух рядов для соответствующей подстроки - я просто не могу думать об этом прямо сейчас!

1
ответ дан 8 December 2019 в 05:55
поделиться

Не знаю, полезен ли еще ответ, но вот решение, вдохновленное кодом @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"])
0
ответ дан 8 December 2019 в 05:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: