如何在Swift中实现一个ROT13函数?
How to implement a ROT13 function in Swift?
我想创建一个接收字符串和 returns 字符串的函数,并将字母替换为字母表中它后面 13 个字母的字母 (ROT13)。我找到了很多例子,不幸的是,由于各种错误,我没能让它发挥作用。例如这个:
var key = [String:String]() // EDITED
let uppercase = Array(arrayLiteral: "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
let lowercase = Array(arrayLiteral: "abcdefghijklmnopqrstuvwxyz")
for i in 0 ..< 26 {
key[uppercase[i]] = uppercase[(i + 13) % 26]
key[lowercase[i]] = lowercase[(i + 13) % 26]
}
func rot13(s: String) -> String {
return String(map(s, { key[[=11=]] ?? [=11=] }))
}
实际上您最初的 Character
s 映射方法很好:
var key = [Character: Character]()
但是这两个数组必须是Characters
:
的数组
let uppercase = Array("ABCDEFGHIJKLMNOPQRSTUVWXYZ".characters)
let lowercase = Array("abcdefghijklmnopqrstuvwxyz".characters)
(备注: 你(几乎)永远不想调用 xxxLiteral:
初始化器
明确地。这样做(几乎)总是隐藏实际问题。)
现在你用来填充字典的代码可以工作了:
for i in 0 ..< 26 {
key[uppercase[i]] = uppercase[(i + 13) % 26]
key[lowercase[i]] = lowercase[(i + 13) % 26]
}
并且转换字符串可以像
那样完成
// map
// String --> Characters ---> Characters -> String
func rot13(s: String) -> String {
return String(s.characters.map { key[[=13=]] ?? [=13=] })
}
这是另一种不使用查找数组的方法:
let input = "Hello World"
func rot13(unicodeScalar: UnicodeScalar) -> UnicodeScalar {
var result = unicodeScalar.value
if 65...90 ~= result { //Detect capital A ... Z
result = (result + 13 - 65) % 26 + 65
}
else if 97 ... 122 ~= result { //Detect lowercase a ... z
result = (result + 13 - 97) % 26 + 97
}
return UnicodeScalar(result)
}
func rot13(_ input: String) -> String {
let resultUSs = input.unicodeScalars.map(rot13)
var resultUSV = String.UnicodeScalarView()
resultUSV.appendContentsOf(resultUSs) //for Swift 2.2
//resultUSV.append(contentsOf: resultUSs) //for Swift 3.0
return String(resultUSV)
}
let output = rot13(input)
print(output)
这是@AMomchilov 的 rot13
的替代版本,它使用 switch
和更少的数学并消除了幻数:
func rot13(_ unicodeScalar: UnicodeScalar) -> Character {
var result = unicodeScalar.value
switch unicodeScalar {
case "A"..."M", "a"..."m":
result += 13
case "N"..."Z", "n"..."z":
result -= 13
default:
break
}
return Character(UnicodeScalar(result)!)
}
func rot13(_ input: String) -> String {
return String(input.unicodeScalars.map(rot13))
}
print(rot13("Uryyb, jbeyq!")) // "Hello, world!"
泛化到 rotN
我采用了上面的 rot13
函数,并通过让它们采用 ClosedRange<UnicodeScalar>
的数组将它们概括为 rotN
。这允许您以非常直接的方式实现 rot13
、rot47
、rot5
以及 rot13
和 rot5
的组合。
func rotN(_ unicodeScalar: UnicodeScalar, intervals:[ClosedRange<UnicodeScalar>]) -> Character {
var result = unicodeScalar.value
for interval in intervals {
let half = (interval.upperBound.value - interval.lowerBound.value + 1) / 2
let halfway = UnicodeScalar(interval.lowerBound.value + half)!
switch unicodeScalar {
case interval.lowerBound..<halfway:
result += half
case halfway...interval.upperBound:
result -= half
default:
break
}
}
return Character(UnicodeScalar(result)!)
}
func rotN(_ input: String, intervals:[ClosedRange<UnicodeScalar>]) -> String {
return String(input.unicodeScalars.map {rotN([=11=], intervals: intervals)})
}
func rot13(_ input: String) -> String {
return rotN(input, intervals:["A"..."Z", "a"..."z"])
}
func rot47(_ input: String) -> String {
return rotN(input, intervals:["!"..."~"])
}
func rot5(_ input: String) -> String {
return rotN(input, intervals:["0"..."9"])
}
func rot13and5(_ input: String) -> String {
return rotN(input, intervals:["A"..."Z", "a"..."z", "0"..."9"])
}
print(rot13("Uryyb, jbeyq!")) // "Hello, world!"
print(rot47("%96 BF:4< 3C@H? 7@I")) // "The quick brown fox"
print(rot5("6 + 7 = 8")) // "1 + 2 = 3"
print(rot13and5("Whyl 9, 6221")) // "July 4, 1776"
这是基于 @AMomchilov's
原 rot13
的 rotN
版本:
func rotN(_ unicodeScalar: UnicodeScalar, intervals:[ClosedRange<UnicodeScalar>]) -> UnicodeScalar {
var result = unicodeScalar.value
for interval in intervals {
let start = interval.lowerBound.value
let length = interval.upperBound.value - start + 1
if interval ~= unicodeScalar {
result = (result + length/2 - start) % length + start
}
}
return UnicodeScalar(result)!
}
func rotN(_ input: String, intervals:[ClosedRange<UnicodeScalar>]) -> String {
return String(input.unicodeScalars.map {Character(rotN([=12=], intervals:intervals))})
}
我想创建一个接收字符串和 returns 字符串的函数,并将字母替换为字母表中它后面 13 个字母的字母 (ROT13)。我找到了很多例子,不幸的是,由于各种错误,我没能让它发挥作用。例如这个:
var key = [String:String]() // EDITED
let uppercase = Array(arrayLiteral: "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
let lowercase = Array(arrayLiteral: "abcdefghijklmnopqrstuvwxyz")
for i in 0 ..< 26 {
key[uppercase[i]] = uppercase[(i + 13) % 26]
key[lowercase[i]] = lowercase[(i + 13) % 26]
}
func rot13(s: String) -> String {
return String(map(s, { key[[=11=]] ?? [=11=] }))
}
实际上您最初的 Character
s 映射方法很好:
var key = [Character: Character]()
但是这两个数组必须是Characters
:
let uppercase = Array("ABCDEFGHIJKLMNOPQRSTUVWXYZ".characters)
let lowercase = Array("abcdefghijklmnopqrstuvwxyz".characters)
(备注: 你(几乎)永远不想调用 xxxLiteral:
初始化器
明确地。这样做(几乎)总是隐藏实际问题。)
现在你用来填充字典的代码可以工作了:
for i in 0 ..< 26 {
key[uppercase[i]] = uppercase[(i + 13) % 26]
key[lowercase[i]] = lowercase[(i + 13) % 26]
}
并且转换字符串可以像
那样完成// map
// String --> Characters ---> Characters -> String
func rot13(s: String) -> String {
return String(s.characters.map { key[[=13=]] ?? [=13=] })
}
这是另一种不使用查找数组的方法:
let input = "Hello World"
func rot13(unicodeScalar: UnicodeScalar) -> UnicodeScalar {
var result = unicodeScalar.value
if 65...90 ~= result { //Detect capital A ... Z
result = (result + 13 - 65) % 26 + 65
}
else if 97 ... 122 ~= result { //Detect lowercase a ... z
result = (result + 13 - 97) % 26 + 97
}
return UnicodeScalar(result)
}
func rot13(_ input: String) -> String {
let resultUSs = input.unicodeScalars.map(rot13)
var resultUSV = String.UnicodeScalarView()
resultUSV.appendContentsOf(resultUSs) //for Swift 2.2
//resultUSV.append(contentsOf: resultUSs) //for Swift 3.0
return String(resultUSV)
}
let output = rot13(input)
print(output)
这是@AMomchilov 的 rot13
的替代版本,它使用 switch
和更少的数学并消除了幻数:
func rot13(_ unicodeScalar: UnicodeScalar) -> Character {
var result = unicodeScalar.value
switch unicodeScalar {
case "A"..."M", "a"..."m":
result += 13
case "N"..."Z", "n"..."z":
result -= 13
default:
break
}
return Character(UnicodeScalar(result)!)
}
func rot13(_ input: String) -> String {
return String(input.unicodeScalars.map(rot13))
}
print(rot13("Uryyb, jbeyq!")) // "Hello, world!"
泛化到 rotN
我采用了上面的 rot13
函数,并通过让它们采用 ClosedRange<UnicodeScalar>
的数组将它们概括为 rotN
。这允许您以非常直接的方式实现 rot13
、rot47
、rot5
以及 rot13
和 rot5
的组合。
func rotN(_ unicodeScalar: UnicodeScalar, intervals:[ClosedRange<UnicodeScalar>]) -> Character {
var result = unicodeScalar.value
for interval in intervals {
let half = (interval.upperBound.value - interval.lowerBound.value + 1) / 2
let halfway = UnicodeScalar(interval.lowerBound.value + half)!
switch unicodeScalar {
case interval.lowerBound..<halfway:
result += half
case halfway...interval.upperBound:
result -= half
default:
break
}
}
return Character(UnicodeScalar(result)!)
}
func rotN(_ input: String, intervals:[ClosedRange<UnicodeScalar>]) -> String {
return String(input.unicodeScalars.map {rotN([=11=], intervals: intervals)})
}
func rot13(_ input: String) -> String {
return rotN(input, intervals:["A"..."Z", "a"..."z"])
}
func rot47(_ input: String) -> String {
return rotN(input, intervals:["!"..."~"])
}
func rot5(_ input: String) -> String {
return rotN(input, intervals:["0"..."9"])
}
func rot13and5(_ input: String) -> String {
return rotN(input, intervals:["A"..."Z", "a"..."z", "0"..."9"])
}
print(rot13("Uryyb, jbeyq!")) // "Hello, world!"
print(rot47("%96 BF:4< 3C@H? 7@I")) // "The quick brown fox"
print(rot5("6 + 7 = 8")) // "1 + 2 = 3"
print(rot13and5("Whyl 9, 6221")) // "July 4, 1776"
这是基于 @AMomchilov's
原 rot13
的 rotN
版本:
func rotN(_ unicodeScalar: UnicodeScalar, intervals:[ClosedRange<UnicodeScalar>]) -> UnicodeScalar {
var result = unicodeScalar.value
for interval in intervals {
let start = interval.lowerBound.value
let length = interval.upperBound.value - start + 1
if interval ~= unicodeScalar {
result = (result + length/2 - start) % length + start
}
}
return UnicodeScalar(result)!
}
func rotN(_ input: String, intervals:[ClosedRange<UnicodeScalar>]) -> String {
return String(input.unicodeScalars.map {Character(rotN([=12=], intervals:intervals))})
}