【问题标题】:Caesar Cipher java my way, doesnt work凯撒密码 java 我的方式,不起作用
【发布时间】:2015-04-09 19:11:51
【问题描述】:

我知道有很多关于 Caesar Cipher 的话题,但我喜欢用自己的方式解决问题。 因此它不起作用,但我想在一些帮助下,我可能会按照我的方式让它工作。我相信你们都知道当你一个人解决问题时那种美好的感觉。

所以这是我的想法。 制作由字母组成的字符数组。 以及带有消息到代码的字符串。 2 for 循环。一个从消息中设置字符的外部, 和通过字母数组扫描的内部。 当消息中的字母遇到数组中的字符时,它会用数组中的第 3 个(3 的键)字符替换他。

这是现在写的一段代码:

    char[] alphabet = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'o', 'p','r','s','t','u', 'v', 'z'};

    String message = " This is message for coding";

    message = message.toLowerCase();
    String codedMsg = ""; 


    for(int i = 0; i < message.length(); i++)
    {

        for(int j =0; j < alphabet.length; j++)
        {
            if(message.charAt(i) == alphabet[j])
            {
    codedMsg += alphabet[j +3 ];

运行良好,但运行时收到以下错误:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 23
        at sifra.main(sifra.java:19)

【问题讨论】:

  • alphabet[j + 3] 在迭代结束时无效
  • 即使你修复了这个异常,代码仍然不能正常工作。 String.replace 将不加选择地替换任何出现的字符,因此您可能会替换已替换的字符。例如。 “abcd”会变成“gefg”,而不是“defg”。
  • 我现在已经解决了,感谢 Alfred Åkesson。只是不知道我应该把固定程序放在这里还是不放。

标签: java


【解决方案1】:

你的问题是你有alphabet[j + 3]。 但是因为j &lt; alphabet.length,所以当j = alphabet.length - 2alphabet[j + 3] 变成alphabet[alphabet.length + 1] 所以你走出了数组。

要解决这个问题,您可以使用alphabet[(j + 3)%alphabet.length]

现在您的代码将运行但不正确。

因为你总是操纵message,它会在内循环中被替换很多次。

for(int j =0; j < alphabet.length; j++)
        {
            if(message.charAt(i) == alphabet[j])
            {
                message = message.replace(message.charAt(i), alphabet[j + 3]); // THIS LINE IS THE PROBLEM

如果我们说message.charAt(i) = a 这将是真的if(message.charAt(i) == alphabet[j]) 并且所有a 将更改为d 所以现在message.charAt(i) = dfor(int j =0; j &lt; alphabet.length; j++) 的3 次迭代后if 语句将是真的再次,字符串中的所有d 将被替换为g 等等。我对这个问题的解决方案如下,但可能还有更多:

     char[] alphabet = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'o', 'p','r','s','t','u', 'v', 'z'};

        String message = " This is message for coding";

        message = message.toLowerCase();
        char[] messageArray = message.toCharArray();

        for(int i = 0; i < message.length(); i++)
        {
            for(int j =0; j < alphabet.length; j++)
            {
                if(message.charAt(i) == alphabet[j]){
                    messageArray[i] = alphabet[(j + 3)%alphabet.length];
                }
            }
        }
        System.out.println(String.copyValueOf(messageArray));

【讨论】:

  • 我想制作解码消息的方法,所以我需要字母[j-3]%alphabet.length,但它不起作用。再次显示索引超出范围。你能帮我吗?
【解决方案2】:

alphabet[j + 3] 超出数组alphabet 的大小。

【讨论】:

    【解决方案3】:

    如 cmets 中所述,问题在于 alphabet[j + 3] 超出了 j 大于或等于 alphabet.length - 3 的范围。我可以建议的解决方案是将alphabet[j + 3] 更改为alphabet[(j + 3) % alphabet.length],一旦索引超出范围,它将具有“循环”行为。

    【讨论】:

    • THx.你能告诉我为什么当我写字母[j-3]%alphabet.length],当我尝试解码消息时它显示索引超出范围吗?
    • @Sinology,j 小于 3 时会发生这种情况,例如alphabet[2 - 3] % alphabet.length 会给你 -1
    • THx Egor,但是 %alphabet.length 不会在其他方向上创建循环行为吗?我的意思是当它达到 0index 时,它会转到数组中的最后一个索引?
    • @Sinology,绝对不是,为什么呢? % 只是余数运算,-1 % 25 不会给你 24,它会给你 -1
    • 所以如果我没有正确理解它就不能这样做,因为每当我从 alphabed(j) 中扣除 smth 时,我最终会收到负索引并且超出范围?你有什么建议吗?
    【解决方案4】:

    正如其他人指出的那样,您的问题是alphabet[j+3] 将超出字母表末尾的范围。这是解决此问题的方法。

    替换这个

    message = message.replace(message.charAt(i), alphabet[j + 3]);
    

    有了这个

    if(j < alphabet.length - 3){
        message = message.replace(message.charAt(i), alphabet[j + 3]);
    }else{
    message = message.replace(message.charAt(i), alphabet[j + 3 - alphabet.length]);
    }
    

    如果字母表接近尾声,这应该循环回到开头。例如,如果输入字符z,则输出c

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多