【问题标题】:JavaScript - Caesar CipherJavaScript - 凯撒密码
【发布时间】:2020-05-31 17:10:59
【问题描述】:

我知道过去有一些关于凯撒密码的帖子,我看过,但我没有找到帮助我解决这个 kata 的答案,因此我的帖子。

语言是 JavaScript。我已经编写了 3 个测试,其中 2 个到目前为止通过了,但第三个没有。我尝试使用嵌套的 for 循环遍历字母表和 str,并比较它们,然后根据数字向上/向下移动字母表索引,然后将该字母推入一个新数组,并返回连接的数组最后。

它适用于正数,但不适用于负数。 (我还应该指出,我还没有想到如何处理空格,我只是想让它先用于单个单词,然后再从那里取出,谢谢!)

任何正确方向的指针将不胜感激。

Kata 说明:

函数 caesarCipher 应该接受一个字符串和一个数字 (n),并返回一个应用了凯撒密码的新字符串。凯撒密码将每个明文字母替换为字母表上下固定数量的不同字母。 N 表示应应用字母表上移或下移的次数。可能是负面的,也可能是正面的。

  E.g.
  caesarCipher('hello', 2)
    --> 'jgnnq'
  caesarCipher('hello world!', -3)
    --> 'ebiil tloia!'

我的测试:

const caesarCipher = require("../katas/caesar-cipher");
const { expect } = require("chai");

describe.only("caesarCipher", () => {
  it("returns an empty string when passed an empty string", () => {
    const alphabet = [
      "a",
      "b",
      "c",
      "d",
      "e",
      "f",
      "g",
      "h",
      "i",
      "j",
      "k",
      "l",
      "m",
      "n",
      "o",
      "p",
      "q",
      "r",
      "s",
      "t",
      "u",
      "v",
      "w",
      "x",
      "y",
      "z"
    ];
    const str = "";
    const num = 2;
    const actualResults = caesarCipher(alphabet, str, num);
    const expectedResults = "";
    expect(actualResults).to.equal(expectedResults);
  });
  it("returns a string with the letters replaced by the number of shifts up the alphabet", () => {
    const alphabet = [
      "a",
      "b",
      "c",
      "d",
      "e",
      "f",
      "g",
      "h",
      "i",
      "j",
      "k",
      "l",
      "m",
      "n",
      "o",
      "p",
      "q",
      "r",
      "s",
      "t",
      "u",
      "v",
      "w",
      "x",
      "y",
      "z"
    ];
    const str = "hi";
    const num = 2;
    const actualResults = caesarCipher(alphabet, str, num);
    const expectedResults = "jk";
    expect(actualResults).to.equal(expectedResults);
  });
  it("returns a string with the letters replaced by the number of shifts down the alphabet", () => {
    const alphabet = [
      "a",
      "b",
      "c",
      "d",
      "e",
      "f",
      "g",
      "h",
      "i",
      "j",
      "k",
      "l",
      "m",
      "n",
      "o",
      "p",
      "q",
      "r",
      "s",
      "t",
      "u",
      "v",
      "w",
      "x",
      "y",
      "z"
    ];
    const str = "dog";
    const num = -3;
    const actualResults = caesarCipher(alphabet, str, num);
    const expectedResults = "ald";
    expect(actualResults).to.equal(expectedResults);
  });
});

我的解决方案:

function caesarCipher(alphabet, str, num) {
  const strToArray = str.split("");
  console.log(strToArray);
  const cipheredStr = [];
  for (let i = 0; i < strToArray.length; i++) {
    for (let j = 0; j < alphabet.length; j++) {
      if (strToArray[i] === alphabet[j] && Math.sign(num) === 1) {
        console.log(Math.sign(num));
        cipheredStr.push(alphabet[(j += num)]);
      } else if (strToArray[i] === alphabet[j] && Math.sign(num) === -1) {
        console.log(Math.sign(num));
        console.log(alphabet[(j -= num)]);
        cipheredStr.push(alphabet[(j -= num)]);
      }
    }
  }
  console.log(cipheredStr.join(""));
  return cipheredStr.join("");
}

结果:

caesarCipher
[]

    ✓ returns an empty string when passed an empty string
[ 'h', 'i' ]
1
1
jk
    ✓ returns a string with the letters replaced by the number of shifts up the alphabet
[ 'd', 'o', 'g' ]
-1
g
-1
r
-1
j
jum
    1) returns a string with the letters replaced by the number of shifts down the alphabet


  2 passing (15ms)
  1 failing

  1) caesarCipher
       returns a string with the letters replaced by the number of shifts down the alphabet:

      AssertionError: expected 'jum' to equal 'ald'
      + expected - actual

      -jum
      +ald
      
      at Context.<anonymous> (spec/caesar-cipher.spec.js:108:30)
      at processImmediate (internal/timers.js:456:21)

【问题讨论】:

  • 嗨@IndigoDreams,请提供代码源/sn-ps 而不是图片。
  • 效果好吗? :)
  • 解决方案可能更简单。我在 wiki 中阅读了算法: charOutIndex = (charInIndex + num) % alphabet.length
  • 所以诀窍是模运算符 %
  • 我以前使用过模运算符,但在这种情况下不必使用它。我去看看,谢谢:)

标签: javascript caesar-cipher


【解决方案1】:

问题是当num 为负时,你正在做映射:

cipheredStr.push(alphabet[(j -= num)]);

num 是否定的。当你减去一个负数时,你所做的就是添加它的绝对值。

相反,您应该这样做:

cipheredStr.push(alphabet[j + num]);

另外,请注意,要计算字母表中的索引,您不需要将= 放在那里。


旁注

我了解您的解决方案正在进行中。您必须考虑:

  • 当您对j + num 求和以进行翻译时会发生什么,它超出了您的字母表范围。 num 的负值也可能发生同样的情况。
  • 在问题的声明中,它指出caesarCipher 应该只接受两个参数,但您将字母表作为第一个参数传递!

祝你的代码好运并继续尝试:)

【讨论】:

  • 好的,谢谢,是的,这是我已经开始考虑但尚未解决的另一件事。我在想我可能只是继续循环回字母表,所以如果 num 将字母超出 Z,那么它只会循环回 A ,反之亦然,但还没有那么远。谢谢大家的建议! :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-28
  • 2014-03-07
  • 2014-02-06
  • 1970-01-01
  • 2013-02-26
  • 2013-03-13
  • 1970-01-01
相关资源
最近更新 更多