Here's an implementation using a Trie-like data structure. It achieves the goal by simply losing information :-)
(I've assumed you only care about strings being prefixes of each other, rather than substrings...)
class LossyTrie
def initialize; @dict = {}; end
def add(str)
# Break the new string apart into characters, traversing down the trie at each step.
# As a side effect, if a prefix of str was already present, it will be forgotten.
# Similarly, if str itself is a prefix of an existing string, nothing will change.
dict = @dict
str.each_char do |c|
dict = (dict[c] ||= {})
end
end
def all_strings
strs = []
def traverse(dict, so_far, &block)
for k, v in dict
if v.empty?
block.call(so_far + k)
else
traverse(v, so_far + k, &block)
end
end
end
traverse(@dict, "") { |leaf| strs << leaf }
strs
end
end
strs = ["Bochum", "Stu", "Stut", "Stuttt", "Stutt", "Stuttgart", "Heesestr.", "Berl", "Berlin"]
trie = LossyTrie.new
strs.each { |s| trie.add(s) }
trie.all_strings # => ["Bochum", "Berlin", "Stuttt", "Stuttgart", "Heesestr."]
ochu? A small suggestion: when you give examples, assign a variable to each input object (e.g,arr = ["Bochum", ...]). That way readers can refer to those variables (e.g.,arr) in comments and answers without having to define them.ochu.