问题:如何判断输入的字符串儿中的每个字符是否都具有唯一性?
我们先来随便定义一个可以输入字符串儿的函数,然后再调用这个函数,看看返回的结果是否和我们预期的结果一致:
func challenge(input: String) -> Bool {
return true
}
challenge(input: "No duplicates") // 应该返回true
challenge(input: "abcdefghijklmnopqrstuvwkyz") // 应该返回true
challenge(input: "AaBbCc") // 应该返回true
challenge(input: "Hello, world") // 应该返回false
很显然,在第4次调用challenge(input: )函数的时候,我们输入了字符串儿“Hello,world”,它显然不符合我们题目的要求,因为该字符串儿中包含了3个l字符,以及两个o字符,最终理应返回false,但是程序运行的结果是返回了true:
所以,我们需要对上面的代码进行相应的改造。具体的思路是:先定义一个可变的Character类型的数组,专门用来存放我们输入的字符,然后遍历输入的所有字符,并且判断该字符是否已经存在于Character类型的数组中,如果存在,则直接返回false,如果不存在,则将该字符存储到Character类型的数组中。用代码表示如下:
func challenge1(input: String) -> Bool {
// 定义一个用来存储字符的数组
var usedLetters = [Character]()
// 遍历输入的字符串儿
for letter in input.characters {
// 判断数组usedLetters中是否已经包含该字符
if usedLetters.contains(letter) {
// 如果包含,则直接返回
return false
}
// 如果不包含,则将该字符存储到数组usedLetters中
usedLetters.append(letter)
}
return true
}
challenge1(input: "No duplicates") // 应该返回true
challenge1(input: "abcdefghijklmnopqrstuvwkyz") // 应该返回true
challenge1(input: "AaBbCc") // 应该返回true
challenge1(input: "Hello, world") // 应该返回false
调用challenge1(input: )函数,重新输入上面的字符串,这回我们可以看到输入“Hello,world”以后,结果返回false了:
很多时候,解决问题的方案不止一种。我们可以利用Set集合中的元素不能重复这一特性来简化上面的代码:
func challenge1b(input: String) -> Bool {
return Set(input.characters).count == input.characters.count
}
challenge1b(input: "No duplicates") // 应该返回true
challenge1b(input: "abcdfghijklmnopqrstuvwxyz") // 应该返回true
challenge1b(input: "AaBbCc") // 应该返回true
challenge1b(input: "Hello, world") // 应该返回false
因为在Set集合中,重复的元素只能算作一次,所以如果我们输入的字符串儿中包含重复的字符,那么最后两边的个数肯定是不相等的,也就是会返回false:
利用Set的特性精简代码以后,效果是一样的,但是效率更高。