如何使用来自另一个字符串(Caesar Cypher)(JAVA)的字符替换字符串中的字符

时间:2017-07-25 03:26:29

标签: java string char caesar-cipher

我正在做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”。

2 个答案:

答案 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);
}