鉴于我有一个包含3个字符串的数组:
["Extra tv in bedroom",
"Extra tv in living room",
"Extra tv outside the shop"]
如何找到所有字符串共有的最长字符串?
答案 0 :(得分:15)
这是一种红宝石的做法。如果你有很多字符串,或者它们很长,你应该使用更高级的算法:
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"])
答案 1 :(得分:2)
This wikipedia article解释了可用于解决该问题的两种算法。
答案 2 :(得分:2)
如果您想搜索所有字符串的开头:
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 .
答案 3 :(得分:1)
也仅适用于字符串的开头。
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
但是我认为应该有一种方法可以轻松地比较匹配子字符串的两个字符串的开头 - 我现在就想不到它了!
答案 4 :(得分:0)
不要认为这一点特别好。
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"])
答案 5 :(得分:0)
不知道响应是否仍然有用,但这是一个受@ 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"])
答案 6 :(得分:0)
一个更好的措辞:
def longest_common_substring(strings)
shortest = strings.min_by(&:size)
max = shortest.size
max.downto(0) do |size|
0.upto(max - size) do |start|
substring = shortest[start, size]
return substring if strings.all? { |string| string.include? substring }
end
end
end