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
JS: how to shift each letter in the given string N places down in the alphabet?
提问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));
回答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
,a
becomesd
,z
becomesc
- Uppercase letters stay uppercase, same for lowercase
- All other non
[a-zA-Z]
characters remain the same
- 将字母表旋转
k
,例如k = 3
,a
变成d
,z
变成c
- 大写字母保持大写,小写字母相同
- 所有其他非
[a-zA-Z]
字符保持不变
Magic Numbers Explained:
幻数解释:
65-90
are the ranges forA-Z
(uppercase letters)97-122
are the ranges fora-z
(lowercase letters)26
is the number of letters in the alphabet
65-90
是A-Z
(大写字母)的范围97-122
是a-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 String
object 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
回答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));