【问题标题】:Bad instruction error Swift 3 and XCode 8错误的指令错误 Swift 3 和 XCode 8
【发布时间】:2017-01-30 21:31:47
【问题描述】:

我最近一直在学习 Swift 3 语法,我认为一个好的第一个项目应该是 Vigenère Cipher。所以我开始在 Playground 中为它创建一个脚本。

问题是我在调用该方法时不断收到错误并且我知道错误是什么,这与我如何调用我的 Dictionary 值以及我打开它的事实有关,但我不知道不知道该怎么办。有什么想法吗?

import Foundation


let alphabet: [String: Int] = ["a": 0, "b": 1, "c": 2, "d": 3, "e": 4, "f": 5, "g": 6, "h": 7, "i": 8,
                           "j": 9, "k": 10, "l": 11, "m": 12, "n": 13, "o": 14, "p": 15, "q": 16,
                           "r": 17, "s": 18,"t": 19, "u": 20, "v": 21, "w": 22, "x": 23, "y": 24, "z": 25]

let alphabet2: [Int: String] = [0: "a", 1: "b", 2: "c", 3: "d", 4: "e", 5: "f", 6: "g", 7: "h", 8: "i",
                            9: "j", 10: "k", 11: "l", 12: "m", 13: "n", 14: "o", 15: "p", 16: "q",
                            17: "r", 18: "s", 19: "t", 20: "u", 21: "v", 22: "w", 23: "x", 24: "y", 25: "z"]


var mess = "I once saw a big mosquito"
var key = "pass"


func cipher(message: String, key: String) -> String{
    var code: [Int] = [] // will hold the encripted code

    // removes whietspace from message and key
    let trimmedMessage = message.trimmingCharacters(in: NSCharacterSet.whitespaces)
    let trimmedKey = key.trimmingCharacters(in: NSCharacterSet.whitespaces)

    // Sets the key the same size as the message
    let paddedTrimmedKey = trimmedKey.padding(toLength: message.characters.count, withPad: trimmedKey, startingAt: 0)

    // separates the message and key into individual characters
    let charTrimmedMessage = Array(trimmedMessage.characters)
    let charPaddedTrimmedKey = Array(paddedTrimmedKey.characters)


    // Compare the values in the key to the message and scrambles the message.
    var i = 0
    for chr in charTrimmedMessage{
        code.append((alphabet[String(chr)]! + alphabet[String(charPaddedTrimmedKey[i])]!) % 26) // <- I think the error comes from this line. Maybe the exclamation marks?
        i += 1
    }


    var cyphr: String = "" // this will hold the return String

    // I think I could have used some sort of "join" function here.
    for number in code{
        cyphr = cyphr + alphabet2[number + 1]!
    }

    return cyphr
}

cipher(message: mess, key: key) // <--- this returns an error, no clue why. The code works and compiles great.

我收到此错误:

如果您能告诉我有关如何改进我的代码以更好地避免此类事情的任何指示。

【问题讨论】:

  • 请将错误的图像替换为包含其等效文本的代码块,以使未来的读者受益。请记住,文本图像与剪贴板、搜索引擎或屏幕阅读器不兼容。

标签: xcode swift3 swift-playground


【解决方案1】:

您的alphabet 字典没有包含在纯文本中的字母“I”、“”的查找值。密码函数因此失败(因为它强制解开一个可选的 nil)

如果您初始化 mess 变量,您将让密码工作

var mess = "ioncesawabigmosquito"
cipher(...) -> "ypgvuttpqcbzcpljkjmh"

要么

  • 更新alphabet 查找字典。例如。添加 ' ' 作为有效输入,更新 alphabet2 以提供反向查找,并将 mod 因子从 26 更改为 27(以考虑新的 ' ' 字符)

  • 事先验证您的输入。 (修剪空格、替换空格、将大写转换为小写/去除无效范围内的字符)

要将您的输入修剪为仅包含字母表中的有效字母,您可以尝试:

let validSet = CharacterSet.init(charactersIn: alphabet.keys.joined())
var messTrimmed = mess.trimmingCharacters(in: validSet.inverted)

请注意,这样做意味着丢失原始消息中的信息


另一个错误:

cyphr = cyphr + alphabet2[number+1]! 应该是cyphr = cyphr + alphabet2[number]!

数字加 1 是不正确的,因为代码数组中的值是以 26 为模计算的,字母表中的最大键值是 25。当强制解包到不存在的键时会导致异常。

例如尝试cipher(message: "ypgvuttpqcbzcpljkjmh", key: "pass") 使其失败。


脚注

顺便说一句,这里是密码函数的一个变体(我没有清理输入;只是展示代码可以如何以函数方式编写)

func cipher2(message: String, key: String) -> String {
    return
        message
        .characters
        .enumerated()
        .map { ($0, String($1)) }
        .map {
            (
                    alphabet[$1]!
                +   alphabet[String(key[key.index(key.startIndex, offsetBy: ($0 % key.characters.count))])]!
            ) % 26
        }
        .map { alphabet2[$0]! }
        .joined()
}

【讨论】:

  • 非常感谢 Benzi,我真的查看了代码,不知道我是怎么错过的。我会研究你的代码。感谢您的帮助。
猜你喜欢
  • 2017-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-10
相关资源
最近更新 更多