我制作了一个程序,旨在运行文本文档(莎士比亚的《李尔王》),并将字母s的所有实例替换为z,将"sir"替换为"dawg"。我有第一种方法,但我很难弄清楚我的另一种方法(旨在取代"先生")有什么问题。
一切看起来都很好,但它一直在说"越界"。我的代码中有任何建议/错误吗?
import java.util.Scanner;
import java.io.*;
public class KingLear
{
public static void main (String[] args) throws FileNotFoundException
{
PrintStream ps = new PrintStream("new_lear.txt");
Scanner fileScan = new Scanner(new File("king_lear.txt"));
Scanner fileScan2 = new Scanner(new File("king_lear.txt"));
String currentLine;
String currentLine2;
while (fileScan2.hasNextLine())
{
currentLine2 = fileScan.nextLine();
ps.println(dawg(currentLine2));
}
while (fileScan.hasNextLine())
{
currentLine = fileScan.nextLine();
ps.println(zReplace(currentLine));
}
}
public static String zReplace (String line)
{
String newLine = "";
for (int i = 0; i < line.length(); i++)
{
char letter = line.charAt(i+1);
if (letter == 's')
newLine += 'z';
else if (letter == 'S')
newLine += 'Z';
else
newLine += letter;
}
return newLine;
}
public static String dawg (String line)
{
String newLine = " ";
for (int i = 0; i < line.length(); i++)
{
char letter = line.charAt(i);
if (line.charAt(i) == 's' && line.charAt(i+1) == 'i' && line.charAt(i+2) == 'r')
{
newLine +="dawg";
}
}
return newLine;
}
}
无需重新发明轮子。只需使用String.replace
,而不用使事情复杂化。
line = line.replace("sir", "dawg");
到目前为止,所有的替换逻辑都可以重写为:
line = line.replace("s", "z").replace("S", "Z").replace("sir", "dawg");
在for循环中,您将真正获得outofbounds
String newLine = "";
for (int i = 0; i < line.length(); i++)
{
//in this line
char letter = line.charAt(i+1);
if (letter == 's')
newLine += 'z';
else if (letter == 'S')
newLine += 'Z';
else
newLine += letter;
}
将其更改为:
// minus another 1 index
for (int i = 0; i < line.length() - 1; i++)
{
//in this line
char letter = line.charAt(i+1);
if (letter == 's')
newLine += 'z';
else if (letter == 'S')
newLine += 'Z';
else
newLine += letter;
}
对于你的"dawg"功能,也可以更改它:
String newLine = " ";
//minus 2 index
for (int i = 0; i < line.length()-2; i++)
{
char letter = line.charAt(i);
if (line.charAt(i) == 's' && line.charAt(i+1) == 'i' && line.charAt(i+2) == 'r')
{
newLine +="dawg";
}
}
您正在越界,因为您正在使用索引中的"+1或+2"访问数组外的索引。
很难判断是什么原因导致了异常。仅仅通过查看代码,似乎这一行可能导致问题
if (line.charAt(i) == 's' && line.charAt(i+1) == 'i' && line.charAt(i+2) == 'r')
请注意,对于每个i,您都在检查位置i+1和i+2。当i = line.length-1
或i = line.length-2
当你浏览每一行时,你会逐个字符。就在这里:
for (int i = 0; i < line.length(); i++)
{
char letter = line.charAt(i);
if (line.charAt(i) == 's' && line.charAt(i+1) == 'i' && line.charAt(i+2) == 'r')
{
newLine +="dawg";
}
}
但如果您在最后一个字符上。它将显示:
i = line.length() - 1;
char letter = line.charAt(i);
if (line.charAt(i) == 's' && line.charAt(i+1) == 'i' && line.charAt(i+2) == 'r')
{
newLine +="dawg";
}
这是一个问题,因为line.charAt(i+2)
将检查不存在的字符。(事实上,它太远了2位。)
要修复此更改:
for (int i = 0; i < line.length(); i++)
至:
for (int i = 0; i < line.length() - 2; i++)
现在它不会读得太远。这应该可以解决您的问题。希望这有帮助:)
编辑:这应该可以解释你的错误,因为它只是有dawgs。
要修复它只打印dawg的错误,您还需要将其他字母附加到newLine
中,如下所示:
for (int i = 0; i < line.length() - 2; i++)
{
char letter = line.charAt(i);
if (line.charAt(i) == 's' && line.charAt(i+1) == 'i' && line.charAt(i+2) == 'r')
{
newLine += "dawg";
i += 3;
}
else if (i == line.length() - 3){ // checks if this is the last possible dawg
newLine += line.charAt(i);
newLine += line.charAt(i + 1);
newLine += line.charAt(i + 2); // adds the last 3 chars to the string
}
else{
newLine += line.charAt(i); // adds text other than dawg to newLine
}
}
使用这种方法,它应该按照你想要的方式工作。然而,就像Robby Cornelissen说的那样,我会研究String.replace()
函数,因为它非常有用,可读性更强。