我正在做caesar-cypher
。尝试将字符串中的所有字符替换为移位字母表中的某个字符。
到目前为止,这是我的代码
public static String caesarify(String str, int key){
String alphabetNormal = shiftAlphabet(0);
String alphabetShifted = shiftAlphabet(key);
for (int i =0; i < str.length();i++){
for (int c =0; c < alphabetNormal.length(); c++) {
if (str.charAt(i) == alphabetNormal.charAt(c)) {
char replacement = alphabetShifted.charAt(c);
str.replace(str.charAt(i), replacement);
}
}
}
return str;
}
public static String shiftAlphabet(int shift) {
int start =0;
if (shift < 0) {
start = (int) 'Z' + shift + 1;
} else {
start = 'A' + shift;
}
String result = "";
char currChar = (char) start;
for(; currChar <= 'Z'; ++currChar) {
result = result + currChar;
}
if(result.length() < 26) {
for(currChar = 'A'; result.length() < 26; ++currChar) {
result = result + currChar;
}
}
return result;
}
我不知道为什么例如“ILIKEDONUTS”的字符串在caesarified
时不会更改为“JMJLFEPOVUT”。
答案 0 :(得分:1)
请勿使用replace()
或任何replace
方法替换String
中给定索引处的字符。它不起作用。你希望
str.replace(str.charAt(i), replacement);
将替换i
的{{1}}个字符。正如在其他(现已删除)答案中指出的那样,str
本身不会更改str.replace
,因此您需要编写
str
但这不起作用。 str = str.replace(str.charAt(i), replacement);
方法不知道您的索引replace()
是什么。它只知道要替换的字符。而且,正如i
所说的javadoc所示,它会替换字符串中的所有字符。因此,假设replace()
为str.charAt(i)
,您希望将其替换为'a'
。此代码将使用'd'
替换所有 a
个字符,包括(1)您在循环中早先已用d
替换的字符,这样就会失败你已经完成的工作;和(2)a
之后的a
个字符,您要用d
替换,但这会失败,因为在循环的后面您会看到d
并将其替换为{ {1}}。
所以你不能使用g
。有许多方法可以替换字符串的replace()
个字符,包括使用i
:
substring()
但如果要替换每个角色,还有更好的方法。一种是从str = str.substring(0, i) + replacement + str.substring(i + 1);
创建StringBuilder
,使用str
的{{1}}方法更改指定索引处的字符,然后将StringBuilder
转换为最后setCharAt
。您应该能够查看javadoc以了解要使用的方法。
更多:在进一步研究之后,我明白为什么它会返回所有的A.这个内部循环有一个错误:
StringBuilder
假设String
为1,当前字符为“C”。您的内部循环最终会在 for (int c =0; c < alphabetNormal.length(); c++) {
if (str.charAt(i) == alphabetNormal.charAt(c)) {
char replacement = alphabetShifted.charAt(c);
str.replace(str.charAt(i), replacement);
}
}
中找到key
;它在C
中找到相应的字符alphabetNormal
,并用alphabetShifted
替换D
。
然后它会循环回来。由于C
中的下一个字符是D
,它现在匹配 new alphabetNormal
,现在是D
,因此又将其更改为str.char(i)
。然后它循环回来,然后......你得到了照片。
答案 1 :(得分:0)
replace below line
str.replace(str.charAt(i), replacement);
With
str= str.replace(str.charAt(i), replacement);
or you can make a String arr and then replace character in that. in the end create a new string from that array and return.
a better version of caesarify():
public static String caesarify(String str, int key){
String alphabetNormal = shiftAlphabet(0);
String alphabetShifted = shiftAlphabet(key);
//create a char array
char[] arr=str.toCharArray();
//always try to create variable outside of loop
char replacement
for (int i =0; i < arr.length();i++){
for (int c =0; c < alphabetNormal.length(); c++) {
if (arr[i] == alphabetNormal.charAt(c)) {
replacement = alphabetShifted.charAt(c);
//replace char on specific position in the array
arr[i]= replacement;
}
}
}
//return arrray as String
return new String(arr);
}