【问题标题】:How can i replace a char in a String using chars from another string (Caesar Cypher)(JAVA)如何使用另一个字符串中的字符替换字符串中的字符(Caesar Cypher)(JAVA)
【发布时间】:2017-07-25 03:26:29
【问题描述】:

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

【问题讨论】:

  • "cypher 是 Neo4j 的图形查询语言"。不要将“密码”标签用于一般密码问题。我已经删除了标签。
  • 为了帮助您,如果我们知道实际输出 是什么 而不仅仅是它不是什么,将会很有帮助。

标签: java string char caesar-cipher


【解决方案1】:

不要使用replace() 或任何replace 方法来替换String 中给定索引处的字符。它不起作用。你希望这样

str.replace(str.charAt(i), replacement);

将替换str 的第i'个字符。正如在另一个(现已删除)答案中指出的那样,str.replace 本身不会改变str,所以你需要写

str = str.replace(str.charAt(i), replacement);

但这不起作用。replace() 方法不知道您的索引i 是什么。它只知道要替换什么字符。而且,正如replace()javadoc 所说,它替换了字符串中的所有 个字符。所以假设str.charAt(i)'a',你想用'd' 替换它。此代码会将 所有 a 字符替换为 d,包括 (1) 在循环前面已替换为 a 的字符,因此这将破坏您已经完成的工作完毕;和 (2) a 后面的字符,您想将其替换为 d,但这会失败,因为在循环的后面您将看到 d 并将其替换为 g

所以你不能使用replace()。有多种方法可以替换字符串的第 i'th 个字符,包括使用 substring()

str = str.substring(0, i) + replacement + str.substring(i + 1);

但如果您要替换每个字符,还有更好的方法。一种是从str 创建一个StringBuilder,使用StringBuildersetCharAt 方法更改指定索引处的字符,然后在最后将StringBuilder 转换回String。您应该可以查看javadoc 以了解使用哪些方法。

更多: 进一步研究后,我明白为什么它会返回所有 A。这个内循环有错误:

    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 为1,当前字符为'C'。你的内部循环最终会在alphabetNormal 中找到C;它在alphabetShifted中找到对应的字符,即D,并将C替换为D

但随后它会循环回来。由于alphabetNormal 中的下一个字符是D,它现在匹配 str.char(i),现在是@987654366 @,因此再次将其更改为 E。然后它循环回来,然后......你得到了图片。

【讨论】:

  • ajb 非常感谢您的帮助,我还没有了解 StringBuilder,但我会尝试阅读更多相关信息,以便更多地了解您的答案。
【解决方案2】:
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);
}

【讨论】:

    猜你喜欢
    • 2021-06-15
    • 2017-03-25
    • 1970-01-01
    • 1970-01-01
    • 2013-07-09
    • 2019-05-14
    • 2016-02-04
    • 2021-12-01
    • 1970-01-01
    相关资源
    最近更新 更多