提问人:Cedric 提问时间:12/19/2020 最后编辑:validCedric 更新时间:12/20/2020 访问量:966
从文本文件中读取行并拆分其内容
Reading lines from a text file and splitting its contents
问:
对于战舰游戏,我想从文本文件中读取值并将它们存储到变量中。 .txt文件示例:
8
Carrier;3*2;3*3;3*4;3*5;3*6
Battleship;5*6;6*6;7*6;8*6
Submarine;5*2;6*2;7*2;
Destroyer;1*7;1*8
第一行表示我的板的大小。
接下来几行的结构表示这艘船,即它的名字以及它在板上的坐标。例如:Carrier 的坐标为:(3,2),(3,3),(3,4),(3,5)(3,6)。
与船舶关联的坐标数是固定的。但是,呈现船舶的线可能会发生变化。
现在,我尝试创建一个名为 Carrier 的数组 int[][],其中 int[0][0] 为 3,int[0][1] 为 2,...,并为每艘船执行此操作。
稍后,始终放在第一行的电路板尺寸应存储在变量中。int size;
到目前为止,我有这个代码。
public void ReadFile(File f) throws FileNotFoundException {
Scanner scanner = new Scanner(f);
int lineNumber = 1;
while(scanner.hasNextLine()){
String line = scanner.nextLine();
if(lineNumber==1){ // Skipping board size for now.
lineNumber++;
continue;
}
String[] coordinates = line.split(";");
String ship = coordinates[0];
System.out.println(ship);
lineNumber++;
}
scanner.close();
}
我尝试使用分隔符,拆分,..但我没有设法找到解决方案。感谢您的帮助!
答:
此外,始终放在第一行的电路板大小应以可变的 int 大小存储;
那么,为什么你的代码只是跳过第一行而不做任何事情呢?
您的逻辑应该被更改,以添加如下内容来读取电路板的大小:
int size = scanner.nextInt();
scanner.nextLine(); // to skip to the next line of data
然后,你使用你的循环来读取所有的船信息:
while(scanner.hasNextLine()){
String line = scanner.nextLine();
String[] coordinates = line.split(";");
String ship = coordinates[0];
System.out.println(ship);
}
编辑:
此字符串数组具有 null 值,因为每艘船的长度 (#coordinates) 都不同。
问题中发布的代码中的 String 数组将没有 null 值。它将仅包含从每行数据中解析的数据。
如果您尝试将数据从此数组复制到另一个固定大小的 2D 数组,则您的逻辑是错误的。当你知道数据的长度不同时,为什么要创建一个固定大小的数组?
从本质上讲,我需要将载波中的所有坐标存储到一个单独的 2D 数组中
我不会使用 2D 数组。相反,我将创建一个包含单个飞船的所有坐标的 ArrayList。然后你需要一个 ArrayList 来保存所有的飞船。所以逻辑是这样的:
ArrayList<ArrayList<Point>> ships = new ArrayList<>();
while(scanner.hasNextLine())
{
...
ArrayList<Point> ship = new ArrayList<>();
for (int i = 1; i < coordinates.length; i++)
{
// split the value in the coordinates array at the given index
// use the two values to create a Point object
Point point = new Point(...);
ship.add( point );
}
ships.add( ship );
}
评论
试试这个代码:
public static void ReadFile(File f) throws FileNotFoundException {
Scanner scanner = new Scanner(f);
int lineNumber = 1;
int size_board;
int [][] boards=new int[4][0];
int index=0;
while(scanner.hasNextLine()){
String line = scanner.nextLine();
if(lineNumber==1){
line=line.replaceAll("[\\n\\t ]", "");
size_board=Integer.parseInt(line);
System.out.println(size_board);
lineNumber++;
continue;
}
int[] board=new int[0];
String[] coordinates = line.split(";");
String ship = coordinates[0];
System.out.println(ship);
int z=0;
for (int i=1;i<coordinates.length ; i++) {
board = Arrays.copyOf(board, board.length+2);
String[] coords=coordinates[i].split("\\*");
board[z++]=Integer.parseInt(coords[0]);
board[z++]=Integer.parseInt(coords[1]);
}
lineNumber++;
boards[index]=Arrays.copyOf(boards[index], board.length);
boards[index++]=board;
}
scanner.close();
}
这是您的另一种选择。这会将船只和坐标收集到 Map<String, List 中>其中字符串键保存“board”或船名,List 包含具有坐标或网格大小的数组数组。
public static void ReadFile(File f) throws FileNotFoundException {
Scanner scanner = new Scanner(f);
int lineNumber = 1;
Map<String, List> gameData = new HashMap<>();
List board = new ArrayList();
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if (lineNumber == 1) {
String[] gridSize = { line };
gameData.put("boardSize", Arrays.asList(gridSize));
lineNumber++;
continue;
}
List<String> values = Arrays.asList(line.split(";"));
List<String[]> coordinates = new ArrayList();
values.subList(1, values.size()).forEach(in -> {
coordinates.add(in.split("(?<![*])[*](?![*])"));
});
gameData.put(values.get(0), coordinates);
lineNumber++;
}
gameData.forEach((k, v) -> {
System.out.print(k);
System.out.println(Arrays.deepToString(v.toArray()));
});
scanner.close();
}
}
评论