【问题标题】:How to create a function that compares a string to an array of strings in a dictionary and assigns points based on key?如何创建一个函数,将字符串与字典中的字符串数组进行比较并根据键分配点?
【发布时间】:2021-08-26 13:51:15
【问题描述】:

问题是:给定一个单词,计算该单词的拼字游戏分数。

我创建了一个字典来跟踪字符及其相关的拼字游戏点。我创建了一个函数来迭代字典数组中的每个字符,如果它包含迭代的字符,它会添加一个点。不幸的是,该函数无法统计重复的字符,我似乎无法理解为什么......

// struct contains the Scrabble Points dictionary

struct Scrabble {
     static let scrabblePoints = [1  : ["AEIOULNRST"],
                           2  : ["DG"],
                           3  : ["BCMP"],
                           4  : ["FHVWY"],
                           5  : ["K"],
                           8  : ["JX"],
                           10 : ["QZ"]]
}


var points = 0

// I can't figure out why my function doesn't iterate over repeated characters...


func pointGenerator(word:String) -> Int {
    for (key, letters) in Scrabble.scrabblePoints {
        for i in letters {
            for j in i {
                 if word.contains(j) {
                    points += key
                }
            }
        }
    }
    return points
}
//score is inaccurate.

【问题讨论】:

  • 检查大小写?
  • 您应该用单词迭代每个character。但是,如果您想在伪代码中保留当前循环,而不是 word.contains(j),但您可能会看到它为什么不起作用,请使用 word.count(for: j)(您需要编写 count(for:)
  • @Sh_Khan 很好——我需要应用一种方法来做到这一点
  • @Larme 感谢您的回复!我不确定我是否理解如何应用您的建议?
  • 意思是pastebin.com/W4222eNw 但仍然如此。您的方法将分数添加到单词的总分中,而它应该获得该单词的分数,然后将其添加到满分中。

标签: arrays swift function dictionary


【解决方案1】:

你在测试什么词?问题似乎在于您可能会将小写字符与大写拼字游戏字符进行比较。

话虽如此,我认为您的解决方案有点过于复杂。例如,为什么scrabblePoints 中的值是一个数组?如果这些值只是字符串,您可以消除generatePoints 中的for 循环之一。

更重要的是,让我们重新考虑一下您设置scrabblePoints 的方式。字典的目的是为您提供直接查找。通过迭代字符,您将消除字典的好处。相反,如果您像这样构建您的字典会怎样:

static let scrabblePoints = ['A'  : 1,
                       'B'  : 3,
                       'C'  : 3,
                       // and so on for all 26 letters
                       ]

这样,您可以直接查找任何给定字符的点值。所以你的generatePoints 变成了:

func pointGenerator(word: String) -> Int {
    for char in word {
        points += Scrabble.scrabblePoints[char.uppercased()]
    }
    return points
}

【讨论】:

  • 太棒了...非常感谢!!!这就是解决方案。
【解决方案2】:

Scrabble 中创建一个函数,通过在字典中找到一个字符来返回它的点

static func point(for character: Character) -> Int {
    Scrabble.scrabblePoints.first(where: { $0.value.contains(character.uppercased()) })?.key ?? 0
}

然后在你的函数中使用它

func pointGenerator(word:String) -> Int {
    word.reduce(into: 0, { $0 += Scrabble.point(for: $1) })
}

请注意,我通过将您的字典更改为 [Int: String] 类型来简化这一点,

static let scrabblePoints = [1  : "AEIOULNRST",
                             2  : "DG",
                             3  : "BCMP",
...

【讨论】:

    【解决方案3】:

    我认为如果您从字母到点进行查找会有所帮助

    extension String {
        var scrabbleScore: Int {
            let letterPoints: [Character:Int] = [
                "A":1,
             "B":3,
             "C":3,
             "D":2,
             "E":1
            ]
            return self.uppercased().reduce(into: 0) { sum, letter in
                sum += letterPoints[letter] ?? 0
            }
        }
    }
    
    "BEAD".scrabbleScore // 7
    

    你也可以这样写,这样可以避免散列:

    extension String {
        var scrabbleScore: Int {
            reduce(into: 0) { sum, letter in
                sum += letter.scrabbleValue
            }
        }
    }
    
    extension Character {
        var scrabbleValue: Int {
            switch self {
            case "A", "E", "I", "a", "e", "i": return 1
            case "B", "C", "b", "c": return 3
            case "D", "d": return 2
            default: return 0
            }
        }
    }
    

    回答您的问题:无论单词包含该字母多少次,您只需为给定字母添加一次分数:

    if word.contains(j) {
                        points += key
                    }
    

    例如,如果单词包含 j 3 次,则需要加分 3 次。

    【讨论】:

    • 谢谢!!!我喜欢扩展方法...谢谢
    【解决方案4】:

    试试这个:

           func pointGenerator(word:String) -> Int {
            for (key, letters) in Scrabble.scrabblePoints {
                for subWord in letters {
                    
                         if word.contains(subWord) {
                            points += key
    //                        print(points)
                        }
                    }
                }
    //        print(points)
    
            return points
        }
    

    【讨论】:

    • 如果字母都是大写的这个方法
    • -感谢您提供答案-这似乎对我不起作用?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多