Считывание информации из файла

Мне необходимо из файла считать в три массива информацию о транспортной задаче.

Например, у меня есть файл, и из него нужно:

В массив A считать:

14.5 10 15

В массив B:

10 15.7 12

И в массив С остальную матрицу.

Пример файла:

8 12 15 5 80 
6 7 9 12 100
12 5 11 10 50
60 60 70 40 

Как это лучше сделать? У меня есть две идеи: либо изначально считывать все в один массив, а потом распределять, но это неудобно; либо же сразу разбить по файлам, но я не представляю, как это тогда реализовать на джаве.

Пример разбития на массивы такой:

private double[] proposition = {14.5,10,15,12};
private double[] demand = {10,15.7,12,15}; 
private double[][] price = {
            {10,30,25,15},
            {20,15,20,10},
            {10,30,20,20},
            {30,40,35,45}};

Кусок кода, который только считывает, но не разбивает на массивы:

public class Files {
    String line;

    // построчное считывание файла
    public String read() {
        try {
            File file = new File("ex3.txt");
            // создаем объект FileReader для объекта File
            FileReader fr = new FileReader(file);
            // создаем BufferedReader с существующего FileReader
            // для построчного считывания
            BufferedReader reader = new BufferedReader(fr);
            // считаем сначала первую строку
            line = reader.readLine();
            while (line != null) {
                // считываем остальные строки в цикле
                line = reader.readLine();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return line;
    }

    public static void main(String[] args) {
        Files files = new Files();
        files.read();
    }
}

Виды записей в файл

В первом варианте магазинов (80,100,50) меньше, в другом (80,100,50) больше. Последняя строка -- всегда покупатели, и считываться должна полностью.


Ответы (2 шт):

Автор решения: Дмитрий

У вас очень странный подход к решению задачи. Ваши интерфейсы работают с 3 массивами , один из которых двухмерный. Это крайне неудобно с точки зрения реализации дальнейшей бизнесс-логики. Но если это уже реализовано и вам действительно необходимо получит данные в таком виде, то я бы предложил сделать специальный класс, который будет вычитывать из файла и готовить для вас все необходимые данные в виде, с которым работают ваши интерфейсы (3 массива). Для реализации нашего класса сделаем 4 метода: 3 из которых будут формировать 3 целевых массива, а четвертый - читать файл в двухмерный исходный массив. Конструктор будет принимать имя файла, вызывать указанные приватные методы, инициализируя поля (3 нужных нам массива). ну и, разумеется, геттеры для того, чтобы получит наши массивы. посему реализация выглядит так:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

public class Matrix {

    private final Double [] shops;
    private final Double [] buyers;
    private final Double [][] prices;

    public Matrix(String fileName) throws IOException {
        final Double[][] sourceArray = readFile(fileName);
        this.shops = createShops(sourceArray);
        this.buyers = createBuyers(sourceArray);
        this.prices = createPrices(sourceArray);
    }

    private Double[][] readFile(String fileName) throws IOException {
        try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
            return stream
                    .map(i -> Arrays.stream(i.split(" "))
                        .peek(String::trim)
                        .map(Double::valueOf)
                        .toArray(Double[]::new))
                    .toArray(Double[][]::new);
        }
    }

    private Double[] createBuyers (Double[][] sourceArray) {
        return Arrays.copyOf(sourceArray[sourceArray.length - 1], sourceArray[sourceArray.length - 1].length);
    }

    private Double[] createShops (Double[][] sourceArray) {
            final List<Double> buyers = new ArrayList<>();
            for (int i = 0; i < sourceArray.length-1; i++) {
                if (sourceArray[0].length==sourceArray[i].length) 
                    buyers.add(sourceArray[i][sourceArray[i].length-1]);
            }
            return buyers.toArray(new Double[buyers.size()]);
    }

    private Double[][] createPrices(Double[][] sourceArray) {
        final Double[][] distArray = new Double[sourceArray.length - 1][sourceArray[0].length - 1];
        for (int i = 0; i < sourceArray.length - 1; i++) 
            System.arraycopy(sourceArray[i], 0, distArray[i], 0, sourceArray[i].length - 1);
        return distArray;
    }

    public Double[] getShops() {
        return shops;
    }

    public Double[] getBuyers() {
        return buyers;
    }

    public Double[][] getPrices() {
        return prices;
    }

}

P.S. хорошенько подумайте переде тем, как считать деньги в double, это совсем треш (никогда так не делайте на реальных проектах, только лонг).

Используем класс так:

import java.io.IOException;
import java.util.Arrays;

public class Main {
    public static void main(String[] args) throws IOException {
        Matrix matrix = new Matrix("ex3.txt");
        System.out.println("************************************************************");
        System.out.println(Arrays.toString(matrix.getShops()));
        System.out.println(matrix.getShops().length);
        System.out.println("************************************************************");
        System.out.println(Arrays.toString(matrix.getBuyers()));
        System.out.println(matrix.getBuyers().length);
        System.out.println("************************************************************");
        System.out.println(Arrays.deepToString((matrix.getPrices())));
        System.out.println("************************************************************");

    }
}
→ Ссылка
Автор решения: Дмитрий Никифоров

Приведу решение в процедурном стиле.

int m = 3; // число строк матрицы затрат (число покупателей)
int n = 4; // число столбцов матрицы затрат (число магазинов)
double[][] c = new double[m][n];
double[] a = new double[m];
double[] b = new double[n];
Scanner sc = new Scanner(new FileInputStream("ex3.txt"));
for (int i = 0; i < m; i++) {
  for (int j = 0; j < n; j++) {
    c[i][j] = sc.nextDouble();
  }
  a[i] = sc.nextDouble();
}
for (int j = 0; j < n; j++) {
  b[j] = sc.nextDouble();
}
System.out.println(Arrays.deepToString(c));
System.out.println(Arrays.toString(a));
System.out.println(Arrays.toString(b));
→ Ссылка