我有以下代码:
func hash (s:String) -> Int {
var z = 19
let key = "abcdefghijk"
for var i = 0; i < s.characters.count; i++ {
let index = s.startIndex.advancedBy(i)
let char = s[index]
if let f = key.characters.indexOf(char) {
print(f) //This outputs the number I want to use in the next line, but as String.CharacterView.Index, not an Int
z = (z * f) //obviously this won't work
}
// So instead we try this:
z = z * s.startIndex.distanceTo(key.characters.indexOf(char)!))
// It works for the first few characters then I get "fatal error: can not increment endIndex" and a EXC_BAD_INSTRUCTION
}
return z
}
我正在努力使用Swift String
来查找我想在某种哈希函数中用作Int
的索引。如果不清楚:
用户输入一个字符串,该函数遍历每个字符,在key
中找到该字符,然后在key
中获取该字符的索引并将其乘以现有的z
计数器。
我得到了我想要的结果,但只是在错误的类型中,我不能转换为Int。谁知道怎么做?
由于
答案 0 :(得分:3)
f = key.characters.indexOf(char)
是字符的索引
key
的{{1}},因此您必须计算到key
的起始索引的距离,而不是s
:
z = z * key.startIndex.distanceTo(key.characters.indexOf(char)!))
您可以将其移回if-let
区块:
if let f = key.characters.indexOf(char) {
z = z * key.startIndex.distanceTo(f)
}
您也可以使用overflow operator &*
if let f = key.characters.indexOf(char) {
z = z &* key.startIndex.distanceTo(f)
}
否则应用程序将崩溃,如果结果
乘法不适合Int
。
通常,只能使用Swift String
的索引
使用相同的字符串(无论字符串长度如何),如下所示
示例演示:
let s1 = "abc"
let i1 = s1.characters.indexOf("b")!
print(i1) // 1
let s2 = "abc"
print(s2.characters.count) // 6
let d2 = s2.startIndex.distanceTo(i1) // fatal error: can not increment endIndex
答案 1 :(得分:1)
如果您将密钥设为Character
个数组,则indexOf
将返回您需要的Int
:
func hash (s:String) -> Int {
var z = 19
let key = Array("abcdefghijk".characters)
for char in s.characters {
if let f = key.indexOf(char) {
print(f)
z = (z &* (f + 1))
}
}
return z
}
此外,如果您的角色是密钥中的第一个索引,您将获得0
的值,这将使您的哈希值0
,因此我已将1
添加到{ {1}}。我还根据@MartinR的建议合并了f
,以防止&*
溢出。
答案 2 :(得分:-1)
首先,不要使用强制解包,因为您最终可能会轻易崩溃您的应用程序(因为它似乎已经发生)。
其次,您已经测试了z
的有效性,您可以将if-let
计算放在z = z * s.startIndex.distanceTo(f)
中:
hash()
您的代码会发生k
函数遇到key
以外的字符时崩溃,因此您还应将所有可能的字符添加到JavaPairRDD: JavaRDD: Desired Output:
1,USA France 2,England
2,Engand England 3,France
3,France
4,Italy
。