Arrays 如何创建一个函数,将字符串与字典中的字符串数组进行比较,并根据键分配点?
问题是:给定一个单词,计算该单词的拼字分数 我已经创建了一个字典来跟踪字符及其相关的拼字点。我创建了一个函数,它迭代字典数组中的每个字符,如果它包含迭代的字符,它会添加一个点。不幸的是,该函数没有计算重复的字符,我似乎不明白为什么Arrays 如何创建一个函数,将字符串与字典中的字符串数组进行比较,并根据键分配点?,arrays,swift,function,dictionary,Arrays,Swift,Function,Dictionary,问题是:给定一个单词,计算该单词的拼字分数 我已经创建了一个字典来跟踪字符及其相关的拼字点。我创建了一个函数,它迭代字典数组中的每个字符,如果它包含迭代的字符,它会添加一个点。不幸的是,该函数没有计算重复的字符,我似乎不明白为什么 // struct contains the Scrabble Points dictionary struct Scrabble { static let scrabblePoints = [1 : ["AEIOULNRST"],
// 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.
试试这个:
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
}
我认为如果你有一个从字母到点的查找,这会有所帮助
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次点数。您正在测试哪些单词?问题似乎在于,您可能正在比较小写字符和大写拼字字符 话虽如此,我认为你的解决方案有点过于复杂了。例如,
scrabblePoints
中的值为什么是数组?如果值只是字符串,则可以在generatePoints
中消除for
循环中的一个
更重要的是,让我们重新思考设置拼字点的方式。字典的目的是为您提供直接查找。通过对字符进行迭代,您将失去字典的优势。相反,如果你的字典结构如下:
static let scrabblePoints = ['A' : 1,
'B' : 3,
'C' : 3,
// and so on for all 26 letters
]
这样,就可以直接查找任何给定字符的点值。因此,您的生成点成为:
func pointGenerator(word: String) -> Int {
for char in word {
points += Scrabble.scrabblePoints[char.uppercased()]
}
return points
}
在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",
...
检查大写/小写?您应该在Word中迭代每个字符。但是,如果您想在伪代码中保留当前循环,而不是word.contains(j)
,但您可能知道它不起作用的原因,请使用word.count(for:j)
(您需要编写count(for:)
?@Sh_Khan很棒的观点-我需要应用一种方法that@Larme感谢您的回复!我不确定我是否理解如何应用您的建议?在“意指但仍然”中。您的方法将分数添加到单词的总分中,而它应该获得该单词的分数,然后您将其添加到满分中。如果字母都是大写的谢谢你提供了一个答案-这似乎对我不起作用?我已经在你的例子上尝试过了,并且很有效…非常感谢!!!这就是解决方案。谢谢!!!我喜欢扩展方法…谢谢哦哇…谢谢!!!