我正在制作Cesar的Cypher,将这些字母移动13位。它有效,但每个单词的最后一个字母都重复了。我知道可能有一种更有效的方式来编写它,但这是我的代码。
debugElement

例如LBH QVQ VG!打印出你的UDID DITT而不是你的DID!此外,我是javascript的新手,所以如果有任何语法,请纠正我。
答案 0 :(得分:0)
这是一个更好的方法:
function chr_to_ord(chr) {
return (chr.toUpperCase().charCodeAt(0)-65); // Convert the ascii to a number in range 0-25 [A-Z]
}
function ord_to_chr(ord) {
return (String.fromCharCode(ord+65)); // Get the char from a number in range 0-25 [A-Z]
}
function convert_chr(chr,n) {
return ord_to_chr((chr_to_ord(chr)+n)%26); // convert one char
}
function convert_str(str,n) {
var res='';
for (var i=0;i<str.length;i++) {
if (chr_to_ord(str[i])>=0 && chr_to_ord(str[i])<=25) { //convert only A-Z a-z chars
res+=convert_chr(str[i],n)
} else {
res+=str[i]; // keep none-alphas
}
}
return res;
}
答案 1 :(得分:0)
你的第一个问题是如果你检测到一个空格你应该continue;
for循环(否则你最后一次使用的字符会被第二次追加):
if (str.substring(i, i + 1) === " ") {
word += " ";
continue;
}
您的第二个问题是,如果您的letters
数组中找不到当前字符,您就不在乎了,在这种情况下,您的代码只使用最后一个z
。< / p>
正如旁注:在你的位置,我会看看JS&#39;内置函数,例如split
,indexOf
,charCodeAt
,fromCharCode
,可以简化您的生活。
答案 2 :(得分:0)
问题在于,当您找到空格并将其复制到结果时,您不会跳过处理该字符的其余代码。由于设置z
的循环永远不会找到匹配项,因此它使用循环的上一次迭代中的z
值,因此它会复制前一个单词的最后一个字符。
如果有标点字符,也会发生同样的事情。在这种情况下,测试空间的代码不会将其复制到结果中,然后你进入查找letters
中的字符的循环,它找不到它,所以它再次使用之前的z
值。
两者的简单解决方案是检查当前字符是否在letters
,而不是专门检查space
。
顺便说一句,您可以使用str[i]
或str.charAt(i)
来获取字符串中的当前字符,而不是str.substring(i, i+1)
。要查找数组的元素,请使用letters.indexOf(char)
而不是显式循环。
function rot13(str) {
var letters = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"];
var word = "";
var z = 30;
for (i = 0; i < str.length; i++) {
var char = str[i];
z = letters.indexOf(char);
if (z == -1) {
word += char;
continue;
}
var n = z + 13; //31
if (n >= 26) {
word = word + letters[13 - (26 - z)];
} else if (n < 26)
word = word + letters[13 + z];
}
return word;
}
console.log(rot13("LBH QVQ VG!"));
&#13;
而不是最后的if
语句,您可以使用模数运算符:
word += letters[n % letters.length];