我喜欢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
}
}
}
只要字符串的长度为奇数,此代码就会失败。当然我可以这样做,所以块的第一行将是if word.characters.count < 2
,但在Swift有一种方法可以获得子串并轻松检查吗?
更新我喜欢很多建议,但我想最初的问题可能会误导一点,因为这是一个关于String的问题而不是为函数获得正确的结果。
例如,在Python中,checkPalindrome(word [1:-1])可以很好地用于递归定义,而Swift代码则不那么优雅,因为它需要其他的花里胡哨。
有时使用前端进行递归可以简化生活。我有时会在最方便使用的参数不是我想要的用户界面时执行此操作。
以下是否满足您的需求?
func checkPalindrome(str: String) -> Bool {
func recursiveTest(var charSet: String.CharacterView) -> Bool {
if charSet.count < 2 {
return true
} else {
if charSet.popFirst() != charSet.popLast() {
return false
} else {
return recursiveTest(charSet)
}
}
}
return recursiveTest(str.characters)
}
将字符串转换为数组。执行循环时获取第一个索引并与最后一个索引进行比较。
func palindrome(string: String)-> Bool{
let char = Array(string)
for i in 0..<char.count / 2 {
if char[i] != char[char.count - 1 - i] {
return false
}
}
return true
}
func checkPalindrome(_ inputString: String) -> Bool {
if inputString.count % 2 == 0 {
return false
} else if inputString.count == 1 {
return true
} else {
var stringCount = inputString.count
while stringCount != 1 {
if inputString.first == inputString.last {
stringCount -= 2
} else {
continue
}
}
if stringCount == 1 {
return true
} else {
return false
}
}
}
func isPalindrome(myString:String) -> Bool {
let reverseString = String(myString.characters.reversed())
if(myString != "" && myString == reverseString) {
return true
} else {
return false
}
}
print(isPalindrome("madam"))
if word == String(word.reversed())
{
return true
}
return false
只是在if中添加更多条件
func checkPalindrome(word: String) -> Bool {
print(word)
if (word == "" || word.characters.count == 1){
return true
}
else {
if word.characters.first == word.characters.last {
return checkPalindrome(word.substringWithRange(word.startIndex.successor() ..< word.endIndex.predecessor()))
} else {
return false
}
}
}
extension String {
var lettersOnly: String {
return componentsSeparatedByCharactersInSet(NSCharacterSet.letterCharacterSet().invertedSet).joinWithSeparator("")
}
var isPalindrome: Bool {
return String(characters.reverse()).lettersOnly.lowercaseString == lettersOnly.lowercaseString
}
}
"Dammit I'm Mad".isPalindrome // true
"Socorram-me subi no onibus em marrocos".isPalindrome // true
你也可以将你的字符串分解为一个字符数组并迭代它们,直到它的一半与它的对应物逐一比较:
func checkPalindrome(word: String) -> Bool {
let chars = Array(word.lettersOnly.lowercaseString.characters)
for index in 0..<chars.count/2 {
if chars[index] != chars[chars.count.predecessor() - index] {
return false
}
}
return true
}
并且修复范围问题的递归版本无法使用endIndex <startIndex形成范围:
func checkPalindrome<T: StringProtocol>(_ word: T) -> Bool where T.Index == String.Index {
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
}
}
}
checkPalindrome("Dammit I'm Mad")
我想如果你像这样扩展String,那么它会让你的生活变得更轻松:
extension String {
var length: Int { return characters.count }
subscript(index: Int) -> Character {
return self[startIndex.advancedBy(index)]
}
subscript(range: Range<Int>) -> String {
return self[Range<Index>(start: startIndex.advancedBy(range.startIndex), end: startIndex.advancedBy(range.endIndex))]
}
}
有了它,您可以将功能更改为:
func checkPalindrome(word: String) -> Bool {
if word.length < 2 {
return true
}
if word.characters.first != word.characters.last {
return false
}
return checkPalindrome(word[1..<word.length - 1])
}
快速测试:
print(checkPalindrome("aba")) // Prints "true"
print(checkPalindrome("abc")) // Prints "false"
并没有真正想到这一点,但我想我想出了一个非常酷的扩展,并认为我会分享。
extension String {
var subString: (Int?) -> (Int?) -> String {
return { (start) in
{ (end) in
let startIndex = start ?? 0 < 0 ? self.endIndex.advancedBy(start!) : self.startIndex.advancedBy(start ?? 0)
let endIndex = end ?? self.characters.count < 0 ? self.endIndex.advancedBy(end!) : self.startIndex.advancedBy(end ?? self.characters.count)
return startIndex > endIndex ? "" : self.substringWithRange(startIndex ..< endIndex)
}
}
}
}
let test = ["Eye", "Pop", "Noon", "Level", "Radar", "Kayak", "Rotator", "Redivider", "Detartrated", "Tattarrattat", "Aibohphobia", "Eve", "Bob", "Otto", "Anna", "Hannah", "Evil olive", "Mirror rim", "Stack cats", "Doom mood", "Rise to vote sir", "Step on no pets", "Never odd or even", "A nut for a jar of tuna", "No lemon, no melon", "Some men interpret nine memos", "Gateman sees name, garageman sees nametag"]
func checkPalindrome(word: String) -> Bool {
if word.isEmpty { return true }
else {
if word.subString(nil)(1) == word.subString(-1)(nil) {
return checkPalindrome(word.subString(1)(-1))
} else {
return false
}
}
}
for item in test.map({ $0.lowercaseString.stringByReplacingOccurrencesOfString(",", withString: "").stringByReplacingOccurrencesOfString(" ", withString: "") }) {
if !checkPalindrome(item) {
print(item)
}
}
我使用下面的扩展来查找数字是Palindrome还是Not。
extension String {
var isPalindrome: Bool {
return self == String(self.reversed())
}
}
extension String {
func trimmingFirstAndLastCharacters() -> String {
guard let startIndex = index(self.startIndex, offsetBy: 1, limitedBy: self.endIndex) else {
return self
}
guard let endIndex = index(self.endIndex, offsetBy: -1, limitedBy: self.startIndex) else {
return self
}
guard endIndex >= startIndex else {
return self
}
return String(self[startIndex..<endIndex])
}
var isPalindrome: Bool {
guard count > 1 else {
return true
}
return first == last && trimmingFirstAndLastCharacters().isPalindrome
}
}
我们首先声明一个从字符串中删除第一个和最后一个字符的函数。
接下来,我们声明一个计算机属性,它将包含检查字符串是否为回文的实际递归代码。
如果字符串的大小小于或等于1,我们立即返回true
(由一个字符组成的字符串,如"a"
或空字符串""
被认为是回文),否则我们检查字符串的第一个和最后一个字符是否相同,我们递归调用isPalindrome
在当前字符串中删除了第一个和最后一个字符。