首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Swift中实现ROT13函数?

如何在Swift中实现ROT13函数?
EN

Stack Overflow用户
提问于 2016-06-10 20:10:33
回答 3查看 991关注 0票数 5

我想要创建一个函数,它接收一个字符串并返回一个字符串,并在字母(ROT13)后面用13个字母替换一个字母。我发现了很多例子,不幸的是,由于各种错误,我没能让它正常工作。例如,这个:

代码语言:javascript
复制
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[$0] ?? $0 }))
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-06-10 20:44:49

实际上,您最初映射Characters的方法很好:

代码语言:javascript
复制
var key = [Character: Character]()

但是这两个数组必须是Characters的be数组

代码语言:javascript
复制
let uppercase = Array("ABCDEFGHIJKLMNOPQRSTUVWXYZ".characters)
let lowercase = Array("abcdefghijklmnopqrstuvwxyz".characters)

(注意:您(几乎)从来不想显式地调用xxxLiteral:初始化器。这样做(几乎)总是隐藏实际问题。

现在,填充字典的代码起作用了:

代码语言:javascript
复制
for i in 0 ..< 26 {
    key[uppercase[i]] = uppercase[(i + 13) % 26]
    key[lowercase[i]] = lowercase[(i + 13) % 26]
}

并且可以将字符串转换为

代码语言:javascript
复制
//                       map
// String --> Characters ---> Characters -> String

func rot13(s: String) -> String {
    return String(s.characters.map { key[$0] ?? $0 })
}
票数 6
EN

Stack Overflow用户

发布于 2016-06-11 01:16:08

这是@AMomchilov的rot13的另一个版本,它使用了一个switch和更少的数学,并消除了神奇的数字:

代码语言:javascript
复制
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。这允许您以非常简单的方式实现rot13rot47rot5以及rot13rot5的组合。

代码语言:javascript
复制
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($0, 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"

下面是一个基于rotN@AMomchilov's原始rot13的版本

代码语言:javascript
复制
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($0, intervals:intervals))})
}
票数 6
EN

Stack Overflow用户

发布于 2016-06-10 21:11:03

下面是另一种方法,它不使用查找数组:

代码语言:javascript
复制
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)
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37756430

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档