問題
據我所知,串s1
是串s2
的一個子集,如果之後的零個或多個字符從s2
除去s1 == s2
;即,如果存在映射的索引的m
s1
使得:
- 每個索引
i
的s1
,s1[i] = s2[m(i)]
;和
- if
i < j
then m(i) < m(j)
。
此外s2
是s1
的超集當且僅當是s1
的s2
一個子集。
請注意,對於s1
成爲s2
的子集,s1.size <= s2.size
必須爲真。
例如:
- 「貓」是「工藝」,因爲如果「r」和「F」被除去後者成爲「貓」的子集。
- 「貓」不是「可愛」的子集,因爲「可愛」沒有「a」。
- 「貓」不是「at」的超集,因爲「cat」.include?(「at」)#=> true`。
- 「貓」不是「制定」的子集,因爲
m(0) = 3
和m(1) = 2
,但m(0) < m(1)
是錯誤的;
算法
子集(並因此超集)是一個傳遞關係,其允許算法顯著效率。我的意思是,如果s1
是s2
的子集並且s2
是s3
的子集,則s1
是s3
的子集。
我將如下進行:
- 創建空集
neither_sub_nor_sup
和longest_sups
和空數組subs_and_sups
。
- 按字長排序單詞,最長的第一個。
- 將
w
加上neither_sub_nor_sup
,其中w
是字典中最長的單詞。
- 對於字典中的每個字隨後
w
(最長至最短),執行以下操作:
- 爲每個元素的
neither_sub_nor_sup
u
確定是否w
是u
一個子集。如果是,請將u
從neither_sub_nor_sup
移動到longest_sups
,並將u
附加到subs_and_sups
。
- 如果一個或多個元素從
neither_sub_nor_sup
移動到longest_sups
,則附加w
到subs_and_sups
;否則將w
加到neither_sub_nor_sup
。
- 返回
subs_and_sups
。
代碼
require 'set'
def identify_subs_and_sups(dict)
neither_sub_nor_sup, longest_sups = Set.new, Set.new
dict.sort_by(&:size).reverse.each_with_object([]) do |w,subs_and_sups|
switchers = neither_sub_nor_sup.each_with_object([]) { |u,arr|
arr << u if w.subset(u) }
if switchers.any?
subs_and_sups << w
switchers.each do |u|
neither_sub_nor_sup.delete(u)
longest_sups << u
subs_and_sups << u
end
else
neither_sub_nor_sup << w
end
end
end
class String
def subset(w)
w =~ Regexp.new(self.gsub(/./) { |m| "#{m}\\w*" })
end
end
例
dict = %w| cat catch craft cutie enact trivial rivert river |
#=> ["cat", "catch", "craft", "cutie", "enact", "trivial", "rivert", "river"]
identify_subs_and_sups(dict)
#=> ["river", "rivert", "cat", "catch", "craft"]
變
不像從最長的詞典處理的話至最短,我們可以代替他們最短責令最長:
def identify_subs_and_sups1(dict)
neither_sub_nor_sup, shortest_sups = Set.new, Set.new
dict.sort_by(&:size).each_with_object([]) do |w,subs_and_sups|
switchers = neither_sub_nor_sup.each_with_object([]) { |u,arr|
arr << u if u.subset(w) }
if switchers.any?
subs_and_sups << w
switchers.each do |u|
neither_sub_nor_sup.delete(u)
shortest_sups << u
subs_and_sups << u
end
else
neither_sub_nor_sup << w
end
end
end
identify_subs_and_sups1(dict)
#=> ["craft", "cat", "rivert", "river"]
基準
(未完待續......)
1 OP指出(在後面的評論),其s1
是不是s2
的子字符串,如果s2.include?(s1) #=> true
。我會假裝我從來沒有看到過,因爲它將扳手投入作品。不幸的是,subset
不再是與附加要求的傳遞關係。我沒有調查這個問題的含義,但我懷疑這意味着需要一個相當粗暴的算法,可能需要對詞典中所有單詞進行兩兩比較。
您可能希望編輯以澄清'subset'和'superset'的定義。 [可能的興趣](http://www.independent.co.uk/arts-entertainment/classical/features/the-enduring-myth-of-music-and-maths-2307387.html)。 –
我確實沒有留下所有這些東西,因爲嚴格來說,這並不在問題的範圍之內,即我在遍歷它時如何展開集合。我想現在我們正在進行不同的對話。 – pgblu