fun*_*ct7 5 recursion palindrome swift
我喜欢Swift的许多功能,但是使用操纵字符串仍然是一大难题。
func checkPalindrome(word: String) -> Bool {
print(word)
if word == "" {
return true
} else {
if word.characters.first == word.characters.last {
return checkPalindrome(word.substringWithRange(word.startIndex.successor() ..< word.endIndex.predecessor()))
} else {
return false
}
}
}
Run Code Online (Sandbox Code Playgroud)
每当字符串的长度为奇数时,此代码都会失败。我当然可以这样做,所以该块的第一行是if word.characters.count < 2
,但是Swift中有没有一种方法可以轻松获取子字符串并进行检查?
更新 我喜欢很多建议,但是我想原来的问题可能会误导人,因为这是关于String的问题,而不是为函数获取正确的结果。
例如,在Python中,checkPalindrome(word [1:-1])适用于递归定义,而Swift代码则不太优雅,因为它需要其他技巧。
小智 5
func isPalindrome(myString:String) -> Bool {
let reverseString = String(myString.characters.reversed())
if(myString != "" && myString == reverseString) {
return true
} else {
return false
}
}
print(isPalindrome("madam"))
Run Code Online (Sandbox Code Playgroud)
extension StringProtocol where Self: RangeReplaceableCollection {
var letters: Self { filter(\.isLetter) }
var isPalindrome: Bool {
let letters = self.letters
return String(letters.reversed()).caseInsensitiveCompare(letters) == .orderedSame
}
}
Run Code Online (Sandbox Code Playgroud)
"Dammit I'm Mad".isPalindrome // true
"Socorram-me subi no onibus em marrocos".isPalindrome // true
Run Code Online (Sandbox Code Playgroud)
您还可以将字符串分解为字符数组并迭代它们,直到其一半与对应的字符进行一一比较:
func checkPalindrome(_ word: String) -> Bool {
let chars = Array(word.letters.lowercased())
for index in 0..<chars.count/2 {
if chars[index] != chars[chars.count - 1 - index] {
return false
}
}
return true
}
Run Code Online (Sandbox Code Playgroud)
递归版本修复了无法形成 endIndex < startIndex 范围的问题:
func checkPalindrome<T: StringProtocol>(_ word: T) -> Bool {
let word = word.lowercased()
.components(separatedBy: .punctuationCharacters).joined()
.components(separatedBy: .whitespacesAndNewlines).joined()
if word == "" || word.count == 1 {
return true
} else {
if word.first == word.last {
let start = word.index(word.startIndex,offsetBy: 1, limitedBy: word.endIndex) ?? word.startIndex
let end = word.index(word.endIndex,offsetBy: -1, limitedBy: word.startIndex) ?? word.endIndex
return checkPalindrome(word[start..<end])
} else {
return false
}
}
}
Run Code Online (Sandbox Code Playgroud)
checkPalindrome("Dammit I'm Mad")
Run Code Online (Sandbox Code Playgroud)