0

所以我一直在尝试制作这个简单的加密程序,但我似乎无法弄清楚一些事情。我需要输入的短语是

This is a very big morning.

当我输入它虽然它返回字符串

This is a ag',rery dug>?/ijeb..w ssadorninjeb..w

相反,我回来了

This is a ajedg>P/..w',rery dg>P/ijedg>P/..w ssadorninjedg>P/..w

我不明白为什么以及如何解决它?我已经学习 java 大约一个月了,所以我还很新鲜,如果有类似的问题已经得到解答,请在此处链接我,我将删除此帖子。

这是代码:

import static java.lang.System.out;
import java.util.Scanner;
class Encryption {
    public static void main(String[] args) {
        Scanner userInput = new Scanner(System.in);
        Crypto user1 = new Crypto();
        out.print("Please enter in a sentence: ");
        String user = userInput.nextLine();
        user1.encrypt(user);
        out.print(user1.getEncrypt());
    }
}

public Crypto() { }
public String myEn;
public void encrypt(String Sentence) {
    myEn = Sentence.replaceAll("v","ag',r")
                   .replaceAll("m" , "ssad")
                   .replaceAll("g" , "jeb..w")
                   .replaceAll("b" , "dg>P/");
}

public String getEncrypt() {
        return myEn;
}
}
4

4 回答 4

2

您获得不同输出的原因是因为链式替换获取先前替换的返回值。因此,在您的情况下,如果有 a v,它将更改为ag',r其中包含 a g。这g将触发replaceAll("g" , "jeb..w")

为避免这种情况发生,您应该更改替换的顺序:

Sentence.replaceAll("g" , "jeb..w")
        .replaceAll("b" , "dg>P/")
        .replaceAll("v","ag',r")
        .replaceAll("m" , "ssad");

但是,前两个替换语句无法修复,因为其中一个替换b为包含 a 的字符串,g反之亦然,因此您可能想要更改要替换的字符。

于 2013-10-18T03:04:29.940 回答
0

正如其他人已经告诉您的那样,问题是您在几次迭代(replaceAll 调用)中替换字符而不是一次。如果您想防止替换用于替换其他字符的字符,您可以使用appendReplacementappendTailMatcher类中。

这是您可以这样做的方法

// We need to store somewhere info about original and its replacement
// so we will use Map
Map<String, String> replacements = new HashMap<>();
replacements.put("v", "ag',r");
replacements.put("m", "ssad");
replacements.put("g", "jeb..w");
replacements.put("b", "dg>P/");

// we need to create pattern which will find characters we want to replace
Pattern pattern = Pattern.compile("[vmgb]");//this will do 

Matcher matcher = pattern.matcher("This is a very big morning.");

StringBuffer sb = new StringBuffer();// this will be used to create
                                     // string with replaced characters

// lets start replacing process
while (matcher.find()) {//first we need to find our characters

    // then pick from map its replacement 
    String replacement = replacements.get(matcher.group());
    // and pass it to appendReplacement method
    matcher.appendReplacement(sb, replacement);

    // we repeat this process until original string has no more
    // characters to replace
}
//after all we need to append to StringBuffer part after last replacement
matcher.appendTail(sb);

System.out.println(sb);

输出:

This is a ag',rery dg>P/ijeb..w ssadorninjeb..w.

瞧。

于 2013-10-18T04:04:50.397 回答
0

当您替换g它的替换包含 ab所以当您替换b's 时,您会从替换中得到所有的b'sg也被替换。也v

你能做的是

Sentence.replaceAll("g" , "jeb..w")
    .replaceFirst("b" , "dg>P/")     // as no g's before b's and only want to replace the first
    .replaceFirst("v","ag',r")
    .replaceFirst("m" , "ssad");

但这仅适用于这一句话。


你可以做什么:

  1. 创建所有要替换的角色的地图并进行替换。
  2. 创建要在原始字符串上替换的每个字符的索引列表。
  3. 颠倒列表的顺序(从高到低)
  4. 从列表中的第一个索引(要替换的最后一个字符)开始,将该索引处的字符替换为地图中的替换字符
  5. 重复 4 反向工作。
于 2013-10-18T03:04:22.440 回答
0

首先,您应该使用replace(),而不是replaceAll()。两者都替换找到的所有匹配项,但 replaceAll() 使用正则表达式进行匹配,replace() 使用纯文本。

接下来,您的替换会互相干扰,因此请使用 StringBuffer 并从第 8 个字符开始工作,然后一次替换一个字符。

解密同样应该从左边开始一次处理一个字符。

于 2013-10-18T03:45:43.667 回答