Với tôi có một mảng của 3 chuỗi:Tìm chuỗi thường gặp trong mảng các chuỗi (ruby)
["Extra tv in bedroom",
"Extra tv in living room",
"Extra tv outside the shop"]
Làm thế nào để tìm ra chuỗi dài nhất tất cả các chuỗi có điểm chung?
Với tôi có một mảng của 3 chuỗi:Tìm chuỗi thường gặp trong mảng các chuỗi (ruby)
["Extra tv in bedroom",
"Extra tv in living room",
"Extra tv outside the shop"]
Làm thế nào để tìm ra chuỗi dài nhất tất cả các chuỗi có điểm chung?
Đây là một cách rubyish làm nó. Bạn nên sử dụng thuật toán nâng cao hơn nếu bạn có một chuỗi các chuỗi hoặc chúng rất dài, mặc dù:
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"])
This wikipedia article giải thích hai thuật toán có thể được sử dụng để giải quyết vấn đề đó.
Và bài viết wiki này cung cấp giải pháp hoàn chỉnh cho hai chuỗi: http://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Longest_common_substring#Ruby –
Nếu bạn muốn tìm kiếm cho sự khởi đầu của tất cả các chuỗi:
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 .
Đừng nghĩ rằng điều này đặc biệt tốt.
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"])
Cũng chỉ cho đầu chuỗi.
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
Nhưng tôi nghĩ phải có cách dễ dàng so sánh đầu chỉ hai chuỗi cho chuỗi con phù hợp - Tôi không thể nghĩ về nó ngay bây giờ!
Không biết liệu phản hồi có hữu ích hay không, nhưng đây là giải pháp lấy cảm hứng từ mã @mckeed và @ 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"])
bạn có nghĩa là chuỗi con 'bất kỳ' hay chỉ nên được so sánh từ đầu? –
Cũng được hỏi tại đây: http://rosettacode.org/wiki/Longest_Common_Subsequence –
@ St.Woland: thực sự, nó phụ thuộc. Đối với ví dụ cụ thể của tôi kết quả sẽ giống nhau. Nhưng lý do tôi hỏi là vì tôi muốn biết tôi có thể làm gì để tìm một mẫu cho "mẫu số chung" cho bất kỳ chuỗi ký tự nào. –