Учитывая у меня есть массив 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 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
input = ["Extra tv in bedroom",
"Extra tv in living room",
"Extra tv outside the shop"]
puts substr( input ) + "."
Extra tv .
И еще один, если вы создаете таблицу с вложенной таблицей, вы получаете индекс, созданный автоматически. Объектное хранилище в целом может сделать это, поскольку созданы скрытые таблицы.
Я думаю, что Xmltypes на основе схемы также сделает это.
-121--2132426-Эта статья Википедии объясняет два алгоритма, которые могут быть использованы для решения этой проблемы.
Не думайте, что это масштабы особенно хорошо.
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"])
Нет, это не сработает, на вашей странице будет определена только вторая функция. Здесь является источником.
-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
Но я думаю, что должен быть способ легко сравнить начало только двух рядов для соответствующей подстроки - я просто не могу думать об этом прямо сейчас!
Не знаю, полезен ли еще ответ, но вот решение, вдохновленное кодом @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"])