用 Java 中的 LinkedHashMap 替换 StringBuilder 中的字符
Replacing characters in StringBuilder with LinkedHashMap in Java
基本上我正在编写一个程序,它接收一大段文本(比如一篇文章),并根据接收到程序中的另外两个字符串行替换字符,如下所示:
uvxftkbsqpznlcwdeijhoamgyr
etaoinsrhldcumfpgwybvkxjqz
程序遍历大文本块中的字符,如果一个字符与最上面几行字符匹配,它会用下面的字符替换它。
我已将两个字符串行放入 LinkedHashMap 以便于访问,但由于某种原因,程序没有正确替换字符。这是我的代码:
public class MyReplacer{
public static void main(String[] args) throws IOException {
String fileName = "";
Scanner in = new Scanner(System.in);
System.out.println("Please enter file name");
fileName = in.nextLine();
BufferedReader readerForText = new BufferedReader(new FileReader(fileName));
Scanner keyFileReader = new Scanner(new File("Key.txt"));
String topLine = "";
String bottomLine = "";
//BufferedReader readerForKeyFile = new BufferedReader(new FileReader("Key.java"));
StringBuilder fileString = new StringBuilder();
List<Character> topList = new ArrayList<Character>();
List<Character> bottomList = new ArrayList<Character>();
try{
String line = readerForText.readLine();
while (line!= null){
fileString.append(line);
fileString.append("\n");
line = readerForText.readLine();
}
fileString.toString().toLowerCase();
System.out.println(fileString);
topLine = keyFileReader.nextLine();
bottomLine = keyFileReader.nextLine();
//Convert top line to char array
char arrayChar1[] = topLine.toCharArray();
for(char a:arrayChar1)
{
topList.add(a);
}
//Convert bottom to char array
char arrayChar2[] = bottomLine.toCharArray();
for(char a:arrayChar2)
{
bottomList.add(a);
}
LinkedHashMap<Character,Character> keyMapper = new LinkedHashMap<Character,Character>();
for(int i = 0;i<topLine.length();++i)
{
keyMapper.put(arrayChar1[i],arrayChar2[i]);
}
//Testing that key and value pair has been read in correctly
for(Map.Entry<Character, Character> entry : keyMapper.entrySet())
{
System.out.print(entry.getKey()+ "\n" + entry.getValue());
}
//Replace letters in fileString
for(int x = 0;x<fileString.length();x++)
{
for(Map.Entry<Character, Character> entry : keyMapper.entrySet())
{
if(fileString.charAt(x)==entry.getKey())
{
fileString.setCharAt(x,entry.getValue());
}
}
}
System.out.println(fileString);
} finally{
readerForText.close();
keyFileReader.close();
}
}
大文本的示例如下所示:
vkpuu mlusvbxfs
然而,当我替换字符时,它看起来像:
wxujj xujzwzkvz
因此没有正确替换字符
任何关于为什么这样做的解释都很好。
谢谢
问题就出在这里
for(int x = 0;x<fileString.length();x++)
{
for(Map.Entry<Character, Character> entry : keyMapper.entrySet())
{
if(fileString.charAt(x)==entry.getKey())
{
fileString.setCharAt(x,entry.getValue());
}
}
}
这应该是
for(int x = 0;x<fileString.length();x++)
{
Character c = keyMapper.get(fileString.charAt(x));
if (c != null)
fileString.setCharAt(x, c);
}
你的方法的问题在于,通过像这样搜索条目,你可以多次更改单个字符。
例如
u -> e -> g -> j
为什么你没有得到正确的答案?
因为这有一个内循环:
for (Map.Entry<Character, Character> entry : keyMapper.entrySet()) {
if (fileString.charAt(x) == entry.getKey()) {
fileString.setCharAt(x, entry.getValue());
}
}
考虑 x = 0 处的第一个字母,首先将 v 替换为 t,然后将 t 替换为 i 等,
所以你可以修改为:
for (Map.Entry<Character, Character> entry : keyMapper.entrySet()) {
if (fileString.charAt(x) == entry.getKey()) {
fileString.setCharAt(x, entry.getValue());
//not need to continue find
break;
}
}
或更简单:
for (int x = 0; x < fileString.length(); x++) {
if (keyMapper.containsKey(fileString.charAt(x))) {
fileString.setCharAt(x, keyMapper.get(fileString.charAt(x)));
}
}
你把事情复杂化了。不要填充 StringBuilder 然后替换字符(只需添加字符),不要创建不必要的变量,不要不必要地循环。
试试这个:
Map<Character, Character> map = new HashMap<>();
for (int i = 0; i < topLine.length(); i++)
map.put(topLine.charAt(i), bottomLine.charAt(i));
String line = readerForText.readLine();
StringBuilder fileString = new StringBuilder();
for (char c : line.toCharArray())
fileString.append(map.get(c));
System.out.println(fileString);
基本上我正在编写一个程序,它接收一大段文本(比如一篇文章),并根据接收到程序中的另外两个字符串行替换字符,如下所示:
uvxftkbsqpznlcwdeijhoamgyr
etaoinsrhldcumfpgwybvkxjqz
程序遍历大文本块中的字符,如果一个字符与最上面几行字符匹配,它会用下面的字符替换它。 我已将两个字符串行放入 LinkedHashMap 以便于访问,但由于某种原因,程序没有正确替换字符。这是我的代码:
public class MyReplacer{
public static void main(String[] args) throws IOException {
String fileName = "";
Scanner in = new Scanner(System.in);
System.out.println("Please enter file name");
fileName = in.nextLine();
BufferedReader readerForText = new BufferedReader(new FileReader(fileName));
Scanner keyFileReader = new Scanner(new File("Key.txt"));
String topLine = "";
String bottomLine = "";
//BufferedReader readerForKeyFile = new BufferedReader(new FileReader("Key.java"));
StringBuilder fileString = new StringBuilder();
List<Character> topList = new ArrayList<Character>();
List<Character> bottomList = new ArrayList<Character>();
try{
String line = readerForText.readLine();
while (line!= null){
fileString.append(line);
fileString.append("\n");
line = readerForText.readLine();
}
fileString.toString().toLowerCase();
System.out.println(fileString);
topLine = keyFileReader.nextLine();
bottomLine = keyFileReader.nextLine();
//Convert top line to char array
char arrayChar1[] = topLine.toCharArray();
for(char a:arrayChar1)
{
topList.add(a);
}
//Convert bottom to char array
char arrayChar2[] = bottomLine.toCharArray();
for(char a:arrayChar2)
{
bottomList.add(a);
}
LinkedHashMap<Character,Character> keyMapper = new LinkedHashMap<Character,Character>();
for(int i = 0;i<topLine.length();++i)
{
keyMapper.put(arrayChar1[i],arrayChar2[i]);
}
//Testing that key and value pair has been read in correctly
for(Map.Entry<Character, Character> entry : keyMapper.entrySet())
{
System.out.print(entry.getKey()+ "\n" + entry.getValue());
}
//Replace letters in fileString
for(int x = 0;x<fileString.length();x++)
{
for(Map.Entry<Character, Character> entry : keyMapper.entrySet())
{
if(fileString.charAt(x)==entry.getKey())
{
fileString.setCharAt(x,entry.getValue());
}
}
}
System.out.println(fileString);
} finally{
readerForText.close();
keyFileReader.close();
}
}
大文本的示例如下所示:
vkpuu mlusvbxfs
然而,当我替换字符时,它看起来像:
wxujj xujzwzkvz
因此没有正确替换字符
任何关于为什么这样做的解释都很好。 谢谢
问题就出在这里
for(int x = 0;x<fileString.length();x++)
{
for(Map.Entry<Character, Character> entry : keyMapper.entrySet())
{
if(fileString.charAt(x)==entry.getKey())
{
fileString.setCharAt(x,entry.getValue());
}
}
}
这应该是
for(int x = 0;x<fileString.length();x++)
{
Character c = keyMapper.get(fileString.charAt(x));
if (c != null)
fileString.setCharAt(x, c);
}
你的方法的问题在于,通过像这样搜索条目,你可以多次更改单个字符。
例如
u -> e -> g -> j
为什么你没有得到正确的答案? 因为这有一个内循环:
for (Map.Entry<Character, Character> entry : keyMapper.entrySet()) {
if (fileString.charAt(x) == entry.getKey()) {
fileString.setCharAt(x, entry.getValue());
}
}
考虑 x = 0 处的第一个字母,首先将 v 替换为 t,然后将 t 替换为 i 等, 所以你可以修改为:
for (Map.Entry<Character, Character> entry : keyMapper.entrySet()) {
if (fileString.charAt(x) == entry.getKey()) {
fileString.setCharAt(x, entry.getValue());
//not need to continue find
break;
}
}
或更简单:
for (int x = 0; x < fileString.length(); x++) {
if (keyMapper.containsKey(fileString.charAt(x))) {
fileString.setCharAt(x, keyMapper.get(fileString.charAt(x)));
}
}
你把事情复杂化了。不要填充 StringBuilder 然后替换字符(只需添加字符),不要创建不必要的变量,不要不必要地循环。
试试这个:
Map<Character, Character> map = new HashMap<>();
for (int i = 0; i < topLine.length(); i++)
map.put(topLine.charAt(i), bottomLine.charAt(i));
String line = readerForText.readLine();
StringBuilder fileString = new StringBuilder();
for (char c : line.toCharArray())
fileString.append(map.get(c));
System.out.println(fileString);