【问题标题】:Reading lines from a text file and splitting its contents从文本文件中读取行并拆分其内容
【发布时间】:2020-12-19 15:39:54
【问题描述】:

对于战舰游戏,我想从文本文件中读取值并将它们存储到变量中。 .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

第一行表示我的棋盘大小。

下一行的结构表示船,即。 e.它的名字和它在棋盘上的坐标。例如: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[][]”,但这在您的代码中不存在。即使您的代码不起作用,它也应该显示您想在哪里做什么,如有必要,通过 cmets。

标签: java java.util.scanner delimiter readfile


【解决方案1】:

另外,总是放在第一行的棋盘尺寸应该存储在一个可变的 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);
}

编辑:

此字符串数组具有空值,因为每艘船的长度(#coordinates)不同。

您问题中发布的代码中的字符串数组不会有空值。它只会包含从每一行数据中解析出来的数据。

如果您尝试将数据从该数组复制到另一个固定大小的二维数组,那么您的逻辑是错误的。明知道数据长度不同,为什么还要创建一个固定大小的数组呢?

本质上,我需要将载体的所有坐标存储到一个单独的二维数组中

我不会使用二维数组。相反,我会创建一个 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 );
}

【讨论】:

  • 感谢您的回复。我尝试了您的解决方案,但是,它创建了一个带有字符串的数组,其中坐标 [0] 包含所有船名(这很棒),但坐标 [1] 包含所有第一个坐标。本质上,我需要将来自载体的所有坐标存储到一个单独的 2D 数组中,将战舰存储在另一个数组中,......此外,这个字符串数组具有空值,因为每艘船的长度(#coordinates)是不同的。谢谢你的时间,camickr!
  • 非常感谢。考虑到我在其他类中的逻辑是建立在我的坐标的二维结构上的,我不得不继续使用它(由于没有时间进行分配)。感谢您的帮助!
【解决方案2】:

试试这个代码:

    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();

    }

【讨论】:

    【解决方案3】:

    这是您的另一种选择。这会将船只和坐标收集到一个 Map 中,其中字符串键包含“板”或船只名称,并且 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();
    
      }
    }
    
    
    

    这是工作副本: https://repl.it/@randycasburn/GlaringSoulfulNet

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-23
      • 2020-12-13
      相关资源
      最近更新 更多