【问题标题】:JS: how to shift each letter in the given string N places down in the alphabet?JS:如何将给定字符串 N 中的每个字母在字母表中向下移动?
【发布时间】:2016-01-10 03:40:04
【问题描述】:

如何将给定字符串中的每个字母在字母表中向下移动 N 个位置?标点、空格和大小写应保持不变。例如,如果字符串是“ac”并且 num 是 2,则输出应该是“ce”。我的代码有什么问题?它将字母转换为 ASCII 并添加给定的数字,然后从 ASCII 转换回字母。最后一行替换空格。

function CaesarCipher(str, num) {

    str = str.toLowerCase();
    var result = '';
    var charcode = 0;

    for (i = 0; i < str.length; i++) {
        charcode = (str[i].charCodeAt()) + num;
        result += (charcode).fromCharCode();
    }
    return result.replace(charcode.fromCharCode(), ' ');

}

我来了

TypeError: charcode.fromCharCode is not a function

【问题讨论】:

标签: javascript string


【解决方案1】:

您需要使用 String 对象将参数传递给 fromCharCode 方法。试试:

function CaesarCipher(str, num) {
    // you can comment this line
    str = str.toLowerCase();

    var result = '';
    var charcode = 0;

    for (var i = 0; i < str.length; i++) {
        charcode = (str[i].charCodeAt()) + num;
        result += String.fromCharCode(charcode);
    }
    return result;

}
console.log(CaesarCipher('test', 2));

我不得不修改 return 语句,因为它给我带来了一个错误

【讨论】:

  • 虽然此代码解决了问题中的直接问题,但它并没有“保持空格、标点符号等完好无损”。这应该在答案中提及,因为它是与其他问题相关联的。
  • 这也不能处理你已经有 Z 的情况,需要将这个 2 向右移动,然后应该到达 B。
  • 恐怕这根本解决不了问题。
  • 它不能解决问题。试试 console.log(CaesarCipher('test', 28));它返回非 ascii 字符。
【解决方案2】:
function caesarCipher(s, k) {
    var n = 26; // alphabet letters amount
    if (k < 0) {
        return caesarCipher(s, k + n);
    }
    return s.split('')
        .map(function (c) {
            if (c.match(/[a-z]/i)) {
                var code = c.charCodeAt();
                var shift = code >= 65 && code <= 90 ? 65 : code >= 97 && code <= 122 ? 97 : 0;
                return String.fromCharCode(((code - shift + k) % n) + shift);
            }
            return c;
        }).join('');
}

使用 String.charCodeAt() 将英文字符转换为 ASCII。

使用 String.fromCharCode() 将 ASCII 转换为英文字符。

试试caesarCipher("always-look-on-the-bright-side-of-life", 10) => "kvgkic-vyyu-yx-dro-lbsqrd-csno-yp-vspo"

caesarCipher("kvgkic-vyyu-yx-dro-lbsqrd-csno-yp-vspo", -10) => “永远看着生活的光明面”

【讨论】:

    【解决方案3】:

    需要考虑将字母表中的最后一个字母移回开头的事实。这是我的看法:

    var input = "Caesar Cipher";
        
    function CaesarCipher(str, num) {
        var alphabet = "abcdefghijklmnopqrstuvwxyz";
        var newStr = "";
    
        for (var i = 0; i < str.length; i++) {
            var char = str[i],
                isUpper = char === char.toUpperCase() ? true : false;
    
            char = char.toLowerCase();
    
            if (alphabet.indexOf(char) > -1) {
                var newIndex = alphabet.indexOf(char) + num;
                if(newIndex < alphabet.length) {
                  isUpper ? newStr += alphabet[newIndex].toUpperCase() : newStr += alphabet[newIndex];
                } else {
                  var shiftedIndex = -(alphabet.length - newIndex);
                    isUpper ? newStr += alphabet[shiftedIndex].toUpperCase() : newStr += alphabet[shiftedIndex];
                }
            } else {
               newStr += char;
            }
        }
        return newStr;
    }
    
    console.log(CaesarCipher(input, 20));

    JSFiddle

    【讨论】:

      【解决方案4】:

      在这里,我刚刚在 HackerRank 上完成了这个 same challenge

      我的解决方案类似于@Alexa-905 提出的解决方案。

      目标:

      • 将字母表旋转k,例如,k = 3a 变为 dz 变为 c
      • 大写字母保持大写,小写相同
      • 所有其他非[a-zA-Z] 字符保持不变

      幻数解释:

      • 65-90A-Z 的范围(大写字母)
      • 97-122a-z 的范围(小写字母)
      • 26 是字母表中的字母数

      解决办法:

      function caesarCipher(s, k) {
          let result = '';
      
          for (let i = 0; i < s.length; i++) {
              const charCode = s.charCodeAt(i);
      
              if (
                  (charCode < 65 || charCode > 122) ||
                  (charCode > 90 && charCode < 97)
              ) {
                  result += s[i];
              } else {
                  let newCharCode = charCode + Math.ceil(k % 26);
      
                  if (charCode >= 97 && newCharCode > 122) {
                      newCharCode = newCharCode - 122 + 96;
                  }
                  if (charCode <= 90 && newCharCode > 90) {
                      newCharCode = newCharCode - 90 + 64;
                  }
      
                  result += String.fromCharCode(newCharCode);
              }
      
          }
      
          console.log(result);
          return result
      }
      
      caesarCipher('F rpb Jxqe.zbfi(h%26) ql zrq altk lk olqxqflkp', 3);
      caesarCipher('26 rb cqn wdvkna xo unccnab rw cqn juyqjknc', 17)
      caesarCipher('65-90 mdq ftq dmzsqe rad M-L (gbbqdomeq xqffqde)', 534);
      caesarCipher('97-122 kbo dro bkxqoc pyb k-j (vygobmkco voddobc)', 425974);
      caesarCipher('Aopz jvkl ybuz ha 454,064 vwlyhapvuz wly zljvuk!', 19);
      caesarCipher('myyux://oxujwk.htr/hfjxfw-nk-ax-wjljc/1', 141235435141);

      【讨论】:

        【解决方案5】:

        fromCharCode 函数不对字符串进行操作,它对全局 String 对象进行操作,就像直接从文档中删除的 String.fromCharCode(65, 66, 67); // "ABC" 一样。

        https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCharCode

        【讨论】:

          【解决方案6】:

          这就是我的解决方案

          function rot13(str) {
            var result = str.split("")
                            .map(function(val) {
                              var letterKey = val.charCodeAt() - 13;
                              if(letterKey < 65){
                                letterKey = 90 - (65 - letterKey - 1);
                              }
                              console.log(letterKey);
                              return String.fromCharCode(letterKey);
                            })
                            .join("");
            return result;
          }

          【讨论】:

            【解决方案7】:

            我知道这有点旧,但我想我会试一试。这是我的看法。

            它占大写和小写。它还可以向前或向后移动任意数量!

            function shift(str, n) {
            	var shifted = '';
            	n = n%26;
            	for (var i = 0; i < str.length; i++) {
            		let code = str[i].charCodeAt();
                let capital = (code > 64 && code < 91) ? true : false;
                if (code < (capital?65:97) || code > (capital?90:122) || n == 0) {
                  shifted += str[i];
                  continue;
                }
                if (n > 0) {
                  if (code > (capital?90:122)-n) {
              			code = n + code - 26;
              		} else {
              			code += n;
              		}
                } else {
                  if (code < (capital?65:97)-n) {
              			code = code + n + 26;
              		} else {
              			code += n;
              		}
                }
            		shifted += String.fromCharCode(code);
            	}
            	return shifted;
            }
            
            console.log(shift('Ebiil, Tloia!', 3));

            【讨论】:

              【解决方案8】:

              试试:

              result += String.fromCharCode(charcode)
              

              取自:http://www.w3schools.com/jsref/jsref_fromCharCode.asp

              【讨论】:

                【解决方案9】:

                解决方法如下。

                注意:这包括滚动小、大写和数字字符。特殊符号按原样呈现。

                 function rotationalCipher(input, rotationFactor) {
                      // Write your code here
                      if (!input || rotationFactor < 0 || rotationFactor > 1000000) {
                        return "";
                      }
                
                      let capitalLetters = [...Array(26).keys()].map((n) => n + 65);
                      let smallLetters = [...Array(26).keys()].map((n) => n + 97);
                      let numerics = [...Array(10).keys()].map((n) => n + 48);
                
                      return input
                        .split("")
                        .map((char) => {
                          let asciiCode = char.charCodeAt();
                
                          if (asciiCode >= 97 && asciiCode <= 122) {
                            let newAsciiCode = smallLetters.indexOf(asciiCode) + rotationFactor;
                            return String.fromCharCode(smallLetters[Math.round(newAsciiCode % 26)]);
                          } else if (asciiCode >= 65 && asciiCode <= 90) {
                            let newAsciiCode = capitalLetters.indexOf(asciiCode) + rotationFactor;
                            return String.fromCharCode(
                              capitalLetters[Math.round(newAsciiCode % 26)]
                            );
                          } else if (asciiCode >= 48 && asciiCode <= 57) {
                            let newAsciiCode = numerics.indexOf(asciiCode) + rotationFactor;
                            return String.fromCharCode(numerics[Math.round(newAsciiCode % 10)]);
                          } else {
                            return char;
                          }
                        })
                        .join("");
                    }
                
                    console.log(rotationalCipher("bB_1c", 10));
                    console.log(rotationalCipher("bB_1c", 100));
                    console.log(rotationalCipher("bB_1c", 9));
                    console.log(rotationalCipher("bB_1cbB_1cbB_1cbB_1cbB_1c", 900));

                【讨论】:

                  猜你喜欢
                  • 2011-09-20
                  • 2020-08-11
                  • 2016-01-01
                  • 1970-01-01
                  • 2020-03-17
                  • 2019-07-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2019-09-29
                  相关资源
                  最近更新 更多