Вы можете использовать это:
func anagrams(word: String, from words: [String]) -> [String] {
let characterCount = word.count
let histogramOfWord = histogram(of: word)
let foundWords = words.filter { otherWord in
//Exit early if the character counts differ
if otherWord.count != characterCount {
return false
}
let h2 = histogram(of: otherWord)
//If they have similar histograms, count that word in
if h2 == histogramOfWord {
return true
}
//Compare the histograms with wildcards taken into consideration
else {
guard let wildCards = histogramOfWord["?"], wildCards > 0 else {
return false
}
let numberOfDifferences: Int = h2.map { entry in
let key = entry.key
let value1 = histogramOfWord[key] ?? 0
let value2 = entry.value
let difference = value2 - value1
return difference >= 0 ? difference : 0
}.reduce(0, +)
return numberOfDifferences == wildCards
}
}
return foundWords
}
Вызывает эту функцию, которая вычисляет частоты каждого символа в строке:
func histogram(of string: String) -> [Character:Int] {
var dictionary: [Character:Int] = [Character:Int]()
for i in 0..<string.count {
let c = string[string.index(string.startIndex, offsetBy: i)]
dictionary[c] = (dictionary[c] ?? 0) + 1
}
return dictionary
}
И вы можете использовать это так:
print(anagrams(word: "MILK", from: ["EGGS", "MILK", "LINK", "LIMK", "TREE"]))
//["MILK", "LIMK"]
print(anagrams(word: "?ILK", from: ["EGGS", "MILK", "LINK", "LIMK", "TREE"]))
//["MILK", "LINK", "LIMK"]
print(anagrams(word: "TREE?", from: ["ARETE", "BERET", "BARTE", "MILKA"]))
//["ARETE", "BERET"]
print(anagrams(word: "TREE", from: ["ATRE", "CRET", "LINK", "RETE", "TREE"]))
//["RETE", "TREE"]