我正在阅读一个格式为 16x16 数独谜题的文本文件。
例如:
F7B-E-A-1--6---D -91AF-0-85D7E4-C 05-69C---乙二醇-3- -C-E-2-B--A-7860 E05---2F-7---1C- -4-8-直流--E-593-- -29---1-D-A-04- D67-A-98----B-F- 9B-D-130C8--F5A- 8F4569EA7D--CB-- 6A---745BFE-12D9 7--1DBFC-A-04--E 5-F9C-61240D-7E- A--7-F-DE-580-2- --0-5E7-F63C--14 CE640-----7B5D9F
我正在尝试将值放入 2D 字符数组中,但是当遇到行尾时,似乎包含 3 个空格。 我尝试使用各种方式,如BufferedReader和FileInputStream,但无济于事。文本文件必须采用该格式,因为我的教授将使用这种格式使用自己的值进行测试。
我用于将文件放入数组列表的代码:
private static ArrayList readFile(File filename)
{
ArrayList records = new ArrayList();
try
{
FileInputStream stream = new FileInputStream(filename);
char current;
while(stream.available() > 0)
{
current = (char)stream.read();
records.add(current);
}
stream.close();
return records;
}
catch (Exception e)
{
System.err.format("Exception occurred trying to read '%s'.", filename);
return null;
}
}
然后,我使用迭代器开始为 2D 数组赋值。当打印出网格时,它看起来很好,但是当检查单个值时,如网格[1][1],它不正确,因为它抛出的间距。
有没有办法逐个字符读取,但避免它放入 3 个空格来表示新行?
好吧,由于您只对十六进制字符和-
真正感兴趣,因此您可以过滤掉其他所有内容。最简单的方法可能是替换:
current = (char)stream.read();
跟:
current = (char)stream.read();
while ("0123456789ABCDEF-".indexOf(current) < 0)
current = (char)stream.read();
但是您可能需要摆弄错误条件以确保它是防弹的。
例如,检查输入循环完成后向records
添加了多少元素。如果records.size()
没有给你 256,则文件有问题。
这将消除文件中的所有格式问题,只有内容才重要(例如,如果需要,您可以在一行中提供所有 256 个字符(。
这遵循了稳健性原则,即"在你接受的东西上要自由,在你生产的东西上要具体"。
您可能还需要重新考虑从文件输入创建数组列表,然后从中构造二维数组的方法。在我看来,您可以使用类似(伪代码(直接创建 2D 数组:
def readPuzzle(file) -> (array, error)
set puzzle to new char[16][16]
set row to 0, col to 0
get next character from file to current
while read okay:
if current in "0123456789ABCDEF-":
if row is 16:
return (puzzle, "too many entries in file")
puzzle[row][col] = current
increment col
if col is 16:
increment row
set col to 0
if row is not 16:
return (puzzle, "not enough entries in file")
return (puzzle, "okay")
这基本上只是从文件中读取所有字符,如果它们有效,则将它们直接添加到数组中。在添加之前,它会检查以确保您尚未填充拼图,并且在处理完所有字符后,它会检查以确保整个拼图已填充。
您提到要放入 2D 字符数组,因此您可能希望忽略 15>的位置:
char[][] sudoku = new char[16][16];
Scanner sc = new Scanner(filename);
String[] temporary = new String[16];
int counter = 0;
while(sc.hasNext){
temporary[counter] = sc.nextLine();
counter ++;
}
for(int i = 0; i < 16; i++){
for(int j = 0; j < 16; j++){
sudoku[i][j] = temporary[i].charAt(j);
}
}
现在,您的 2d 数组将自动忽略末尾的空白,因为您逐行读取文件,并手动将值添加到 2d 数组中。
String.trim()
是从字符串的开头或结尾删除不必要的空格的最简单方法,因此一旦读取文件,您始终可以执行清理过程:
private static void trimAllStrings(List<String> list) {
for (int i = 0; i < list.size(); i++) {
list.put(i, list.get(i).trim());
}
}
或者,您可以在读取 - Java 8 的Files.lines()
流中的内容时进行修剪,使这种转换变得非常容易:
List<String> trimmedLines = Files.lines(myfile, StandardCharsets.UTF_8)
.map(String::trim).collect(Collectors.toList());
如果你还没有掌握这个Java 8语法,你可以在Java 7风格中做基本上相同的事情:
ArrayList<String> list = new ArrayList<>();
for (String line : Files.readAllLines(myfile, StandardCharsets.UTF_8)) {
list.add(line.trim());
}