javascript JS:如何将给定字符串中的每个字母在字母表中向下移动 N 个位置?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33084862/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 16:06:08  来源:igfitidea点击:

JS: how to shift each letter in the given string N places down in the alphabet?

javascriptstring

提问by Sammy

how to shift each letter in the given string N places down in the alphabet? Punctuation, spaces, and capitalization should remain intact. For example if the string is "ac" and num is 2 the output should be "ce". What's wrong with my code? It converts letter to ASCII and adds given number then converts from ASCII to letter back. The last line replaces space.

如何将给定字符串中的每个字母在字母表中向下移动 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(), ' ');

}

I'm getting

我越来越

TypeError: charcode.fromCharCode is not a function

回答by Ally Ripp

You need to pass an argument to the fromCharCode method using the String object. Try:

您需要使用 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));

I had to modify the return statement, because it was introducing a bug for me

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

回答by Alexa-905

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('');
}

Use String.charCodeAt() to convert the English character to ASCII.

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

Use String.fromCharCode() to convert ASCII to English character.

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

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

尝试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)=> "always-look-on-the-bright-side-of-life"

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

回答by robjez

One need to take into account fact of shifting last letters in alphabet back to beginning. Here is my take on that:

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

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

JSFiddle

回答by Akmal Salikhov

That's my solution

这就是我的解决方案

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;
}

回答by AnonymousSB

Tossing my hat into the fray here, as I just completed this same challengeover on HackerRank.

把我的帽子扔到这里来,因为我刚刚在 HackerRank 上完成了同样的挑战

My solution is similar to the one proposed by @Alexa-905.

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

Objectives:

目标:

  • Rotate the alphabet by k, e.g., k = 3, abecomes d, zbecomes c
  • Uppercase letters stay uppercase, same for lowercase
  • All other non [a-zA-Z]characters remain the same
  • 将字母表旋转k,例如k = 3a变成dz变成c
  • 大写字母保持大写,小写字母相同
  • 所有其他非[a-zA-Z]字符保持不变

Magic Numbers Explained:

幻数解释:

  • 65-90are the ranges for A-Z(uppercase letters)
  • 97-122are the ranges for a-z(lowercase letters)
  • 26is the number of letters in the alphabet
  • 65-90A-Z(大写字母)的范围
  • 97-122a-z(小写字母)的范围
  • 26是字母表中的字母数

Solution:

解决方案:

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);

回答by linuxdan

The fromCharCode function doesn't operate on strings, it operates on the global Stringobject like so String.fromCharCode(65, 66, 67); // "ABC"ripped off straight from the docs.

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

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

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

回答by MyLittleDax

Try:

尝试:

result += String.fromCharCode(charcode)

Taken from: http://www.w3schools.com/jsref/jsref_fromCharCode.asp

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

回答by Andrew

I know this is a bit old but I thought I'd give it a go. Here's my take on it.

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

It accounts for uppercase and lowercase. It can also shift either forwards or backwards any amount!

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

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));