带有通配符(或说笑话者)的Swift字谜

时间:2018-09-28 15:37:27

标签: swift wildcard anagram

基于Swift中的此功能:

func anagrams(word: String, from words: [String]) -> [String] {
    let anagrammedWord = word as NSString
    let length = anagrammedWord.length
    var aDic = [unichar:Int]()
    for i in 0..<length {
        let c = anagrammedWord.character(at: i)
        aDic[c] = (aDic[c] ?? 0) + 1
    }
    let foundWords = words.filter {
        let string = $0 as NSString
        guard length == string.length else { return false }
        var bDic = [unichar:Int]()
        for i in 0..<length {
            let c = string.character(at: i)
            let count = (bDic[c] ?? 0) + 1
            if count > aDic[c] ?? 0 {
                return false
            }
            bDic[c] = count
        }
        return true
    }
    return foundWords
}

我正在尝试使用通配符,但事实并非如此。 如何使用?_进行检查?

编辑:

它是这样工作的:

input : anagrams(word: "MILK", from: ["EGGS", "MILK", "LINK", "LIMK", "TREE"])
output : ["MILK", "LIMK"]

我想使用通配符,例如:

input : anagrams(word: "?ILK", from: ["EGGS", "MILK", "LINK", "LIMK", "TREE"])
output : ["MILK", "LINK", "LIMK"]

1 个答案:

答案 0 :(得分:1)

您可以使用此:

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"]