I like many of the features in Swift, but using manipulating strings are still a big pain in the ass.
我喜欢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
}
}
}
This code fails miserably whenever the string's length is an odd number. Of course I could make it so the first line of the block would be if word.characters.count < 2
, but is there a way in Swift to get substrings and check easily?
只要字符串的长度为奇数,此代码就会失败。当然我可以这样做,所以如果word.characters.count <2,那么块的第一行就是,但是在Swift中是否有办法获得子串并轻松检查?
Update I like many of the suggestions, but I guess the original question could be misleading a little, since it's a question about String more than getting the right results for the function.
更新我喜欢很多建议,但我想最初的问题可能会误导一点,因为这是一个关于String的问题,而不是为函数获得正确的结果。
For instance, in Python, checkPalindrome(word[1:-1]) would work fine for the recursive definition, whereas Swift code is much less graceful since it needs other bells and whistles.
例如,在Python中,checkPalindrome(word [1:-1])可以很好地用于递归定义,而Swift代码则不那么优雅,因为它需要其他的花里胡哨。
7 个解决方案
#1
3
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
You can also break your string into an array of characters and iterate through them until its half comparing one by one with its counterpart:
你也可以将你的字符串分解成一个字符数组并迭代它们,直到它的一半与它的对应物逐一比较:
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
}
#2
2
Sometimes having a front end for a recursion can simplify life. I sometimes do this when the arguments which are most convenient to use are not what I want in the user interface.
有时候有一个递归的前端可以简化生活。我有时会在最方便使用的参数不是我想要的用户界面时执行此操作。
Would the following meet your needs?
以下是否满足您的需求?
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)
}
#3
1
just add on more condition in if
只需在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
}
}
}
#4
1
I think if you make an extension to String like this one then it will make your life easier:
我想如果你像这样扩展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))]
}
}
With it in place, you can change your function to this:
有了它,您可以将功能更改为:
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])
}
Quick test:
快速测试:
print(checkPalindrome("aba")) // Prints "true"
print(checkPalindrome("abc")) // Prints "false"
#5
1
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
}
}
}
#6
0
Wasn't really thinking of this, but I think I came up with a pretty cool extension, and thought I'd share.
并没有真正想到这一点,但我想我想出了一个非常酷的扩展,并认为我会分享。
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)
}
}
#7
0
func isPalindrome(myString:String) -> Bool {
let reverseString = String(mainString.characters.reverse())
if(mainString != "" && mainString == reverseString) {
return true
} else {
return false
}
}
#1
3
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
You can also break your string into an array of characters and iterate through them until its half comparing one by one with its counterpart:
你也可以将你的字符串分解成一个字符数组并迭代它们,直到它的一半与它的对应物逐一比较:
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
}
#2
2
Sometimes having a front end for a recursion can simplify life. I sometimes do this when the arguments which are most convenient to use are not what I want in the user interface.
有时候有一个递归的前端可以简化生活。我有时会在最方便使用的参数不是我想要的用户界面时执行此操作。
Would the following meet your needs?
以下是否满足您的需求?
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)
}
#3
1
just add on more condition in if
只需在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
}
}
}
#4
1
I think if you make an extension to String like this one then it will make your life easier:
我想如果你像这样扩展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))]
}
}
With it in place, you can change your function to this:
有了它,您可以将功能更改为:
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])
}
Quick test:
快速测试:
print(checkPalindrome("aba")) // Prints "true"
print(checkPalindrome("abc")) // Prints "false"
#5
1
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
}
}
}
#6
0
Wasn't really thinking of this, but I think I came up with a pretty cool extension, and thought I'd share.
并没有真正想到这一点,但我想我想出了一个非常酷的扩展,并认为我会分享。
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)
}
}
#7
0
func isPalindrome(myString:String) -> Bool {
let reverseString = String(mainString.characters.reverse())
if(mainString != "" && mainString == reverseString) {
return true
} else {
return false
}
}