JS:如何将给定字符串中的每个字母N置于字母表中?

时间:2015-10-12 15:30:29

标签: javascript string

如何移动给定字符串中的每个字母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

8 个答案:

答案 0 :(得分:9)

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

&#13;
&#13;
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));
&#13;
&#13;
&#13;

我不得不修改return语句,因为它为我引入了一个bug

答案 1 :(得分:3)

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

&#13;
&#13;
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));
&#13;
&#13;
&#13;

JSFiddle

答案 2 :(得分: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 :(得分:1)

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

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

答案 4 :(得分:1)

那是我的解决方案

&#13;
&#13;
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;
}
&#13;
&#13;
&#13;

答案 5 :(得分:0)

尝试:

result += String.fromCharCode(charcode)

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

答案 6 :(得分:0)

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

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

&#13;
&#13;
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));
&#13;
&#13;
&#13;

答案 7 :(得分:0)

在我刚刚在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);