JavaScript将字符串中的每个字母替换为字母错误后面的字母

时间:2015-10-17 08:21:57

标签: javascript

我正在尝试将字符串中的每个字母替换为字母表后面的字母。

示例:

a -> b  
b -> c  
c -> d  

等等。

function LetterChanges(str) {
    for (var i = 0; i < str.length; i++) {
        if (96 < str.charCodeAt(i) && str.charCodeAt(i) < 123) {
            str = str.replace(str.charAt(i), String.fromCharCode(str.charCodeAt(i) + 1));
        }
    }
    return str;
}

所以我测试的是一些字符串输入,我在“cod”上收到错误,我的代码返回“epd”而不是“dpe”,有人可以帮我修复它吗?

感谢。

5 个答案:

答案 0 :(得分:4)

让我们看看代码将对输入cod执行的操作:

  • 流程c,字母表中的下一个字母为dc替换d,结果为dod
  • 流程o,字母表中的下一个字母为po替换p,结果为dpd
  • 流程d,字母表中的下一个字母为ed替换e,结果为epd

您在第3步看到错误了吗? replace以您使用它的方式替换第一次出现的字母。一种解决方案是通过向其添加下一个字母来创建新字符串。例如:

var newString = '';
for (var i = 0; i < str.length; i++) {
    if (96 < str.charCodeAt(i) && str.charCodeAt(i) < 123) {
        newString += String.fromCharCode(str.charCodeAt(i) + 1);
    }
 }
 return newString;

顺便说一下,你的代码也有一个微妙的bug。如果您的字符串包含z,则会替换{。您可能希望返回到字母表的开头,并在这种情况下将其替换为a

答案 1 :(得分:3)

由于replace不限于字符串中的特定位置,因此每次都会替换第一个匹配字符。 (它不会替换 all ,因为它没有设置g修饰符。)首先,您的前导cd替换,下一轮将o替换为p - 然后,在第三轮中,当您的输入已经dpd时,结果会得到epd,因为第一个{{1} }已被d取代。

如果你没有使用e,但只是构建一个 new 字符串,这会更容易,你每次都要为当前输入字符追加匹配的“next”字符,然后在最后你只需返回那个新字符串。

编辑:

此外,您当前的实现无法正确处理replace,因为它将其替换为“下一个”字符z,而应该是{。而a变为Z,应该是[。在AZ之间,还有一些非字母字符,您可能也不想替换它们。

这是一个实现我上面建议的功能,同时考虑了az以及非字母:

Z

http://jsfiddle.net/hvyft64p/3/

function LetterChanges(str) {
    var result = "";
    for (var i = 0; i < str.length; i++) {
        // handle "z"
        if (122 == str.charCodeAt(i)) {
            result += "a";
        // handle "Z"
        } else if (90 == str.charCodeAt(i)) {
            result += "A";
        // handle all other letter characters
        } else if ((65 <= str.charCodeAt(i) && str.charCodeAt(i) <= 89) ||
                   (97 <= str.charCodeAt(i) && str.charCodeAt(i) <= 121)) {
            result += String.fromCharCode(str.charCodeAt(i) + 1);
        // append all other characters unchanged
        } else {
            result += str.charAt(i);
        }
    }
    return result;
}

console.log(LetterChanges("AaZz+cod!foo")); // output: BbAa+dpe!gpp

我在这里使用65/89和97/121以及if ((65 <= str.charCodeAt(i) && str.charCodeAt(i) <= 89) || (97 <= str.charCodeAt(i) && str.charCodeAt(i) <= 121)) 进行比较,因为从逻辑的角度来看它对我来说更有意义 - 这些是我们想要的实际“边界”字母在这里考虑A / Y和a / y,所以直接使用这些数字使代码更具可读性。

答案 2 :(得分:0)

在循环时更改str不是一个好主意。

这是适用的功能。

function LetterChanges(str) {
    var strOut='';
    for (var i = 0; i < str.length; i++) {
        if (96 < str.charCodeAt(i) && str.charCodeAt(i) < 123) {
            strOut += String.fromCharCode(str.charCodeAt(i) + 1);
        }
    }
    return strOut;
}

答案 3 :(得分:0)

对我来说看起来像是经典的Cezar的密码(对于较低的alplha和右移)

function cezarCipher(str,step){
var res="";
step=step%26; //make sure the step is in range
for(var i=0,j=str.length;i<j;i++){
    var nextCode=str.charCodeAt(i)+step;
    if(nextCode>122){
        nextCode=96+(nextCode-123+1);
    }
    res+=String.fromCharCode(nextCode);
}
return res;
}

使step = 1得到你的结果。

答案 4 :(得分:-1)

function nextLetter(str) {
  return Array
    .from(str)
    .map((letter) => letter.charCodeAt() + 1)
    .map((code) => String.fromCharCode(code))
    .join('');
}

console.log(nextLetter('abc')); // bcb
console.log(nextLetter('hal')); // ibm
console.log(nextLetter('great')); // hsfbu