Strumienie, odczyt z pliku tekstowego do tablicy

0

Witam!
Mam za zadanie odczytać z pliku tekstowego dane, które muszę następnie zapisać w tablicy, a następnie policzyć ich średnią.
Tak wygląda plik tekstowy:

  1. wiersz to zwykły napis, 2. wiersz to liczba wierszy tablicy, z której dane zapisałem do pliku, 3. to liczba kolumn tej samej tablicy, a kolejne wiersze to dane, ktore musze umiescic w nowej tablicy i policzyć ich średnią. W tym momencie zaczynają się schody, bo nie wiem jakiej metody z BufferedReader'a użyć, aby odczytać np. wartość 9,667 z pliku i zapisać ją do tablicy[0][0]
Macierz
5
5
9,667 1,376 9,458 4,950 6,158 
9,505 2,835 9,775 9,223 6,354 
9,864 2,528 2,542 4,290 9,213 
2,433 2,246 8,272 2,286 5,379 
5,901 9,155 8,282 1,197 5,104 
 

Tutaj wklejam tę metodę do momentu do którego potrafiłem ją napisać:

     public void SredniaZpliku(File f) throws IOException
    {
        BufferedReader bufR = new BufferedReader(new FileReader(f));
        bufR.readLine();
        String liczbaWierszy = bufR.readLine();
        String liczbaKolumn = bufR.readLine();
        int iloscWierszy=Integer.valueOf(liczbaWierszy);
        int iloscKolumn=Integer.valueOf(liczbaKolumn);
        double [][] tablica = new double[iloscWierszy][iloscKolumn];
            for(int i=0; i<tablica.length; i++)
            {
                for(int j=0; j<tablica[i].length; j++)
                {
                     tablica[i][j]=       // najpierw napisałem coś takiego: tablica[i][j]=Double.valueOf(bufR.readLine()); , ale szybko 
                                              // zobaczyłem, że to nie ma sensu i utknąłem
                }
            }
    }
}

Mam też kolejne pytanie. Zakładając, że udało mi się te dane poprawnie zapisać w nowej tablicy to, aby tego dokonać musiałbym, w którymś momencie wszystkie przecinki oddzielające część dziesiętną w jakiś sposób zamienić na kropki czy kompilator zrobi to za mnie? (w pliku txt są zapisane wartości typu 2,345 zamiast 2.345 i stąd moje pytanie)

1

Tak najprościej na początek, użyj dla każdej linii:

BuferReader::readLine
String::split
(String::replaceAll , .)
Double:parseDouble
0

Próbuje w jakiś sensowny sposób użyć funkcji String::split, o której mi powiedziałeś, ale niestety nie mam pomysłu.
Napisałem sobie kawałek kodu "na piechotę", żeby zobaczyć jak to działa, ale jestem pewien, że można to ładnie w tablice wrzucić i wykonać za pomocą pętli. Może mała podpowiedź?;)
Tu wklejam kod, żeby pokazać swój tok rozumowania:

         String w1,w2,w3,w4,w5;
        w1=bufR.readLine();
        String [] czesci = w1.split(" ");
        for(int i=0; i<5; i++)
        {
            System.out.print("["+i+"]: "+czesci[i]+" ");
        }
        System.out.println();

0

A spróbuj sobie odpalić z czymś takim w miejscu fora:

for(int i=0; i<tablica.length; i++) {
   String[] line = bufR.readLine().split(" ");
   System.out.println(Arrays.toString(line));
   tablica[i] = line;
}
0

Działa ta pętla, dla przykładowego pliku:

6,216 5,426 3,148 5,665 1,123 
3,978 8,051 7,537 2,387 2,866 
8,942 4,203 4,079 6,483 3,606 
6,122 9,568 2,935 8,957 7,094 
7,933 9,933 9,675 1,581 8,686 

kompilator zwraca:

[6,216, 5,426, 3,148, 5,665, 1,123]
[3,978, 8,051, 7,537, 2,387, 2,866]
[8,942, 4,203, 4,079, 6,483, 3,606]
[6,122, 9,568, 2,935, 8,957, 7,094]
[7,933, 9,933, 9,675, 1,581, 8,686]

Tylko jako, że pierwszy raz spotykam się z takim zapisem:

System.out.println(Arrays.toString(line)); 

Nie rozumiem czemu gdy w kolejnej pętli próbuję wywołać tablica[i]
to otrzymuje:

for(int i=0;i<tablica.length;i++)
        {
            System.out.println(tablica[i]);
        }
[Ljava.lang.String;@5cad8086
[Ljava.lang.String;@6e0be858
[Ljava.lang.String;@61bbe9ba
[Ljava.lang.String;@610455d6
[Ljava.lang.String;@511d50c0

0

Bo tak nie wypisuje się zawartości tablicy. Możesz to zrobić tak jak ja zrobiłem albo poszukaj sobie innego sposobu. Tutaj możesz przeczytać o tym co wypisujesz: https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#toString()

1

W końcu wydaje mi się, że dobrze napisałem ten program. Dziękuję za pomoc, każda odpowiedz mnie w jakimś stopniu naprowadziła na poprawne(chyba) rozwiązanie ;)
Wklejam kod jeżeli ktoś chciałby zobaczyć jak to wyszło:

  public void SredniaZpliku(File f) throws IOException {
        BufferedReader bufR = new BufferedReader(new FileReader(f));
        bufR.readLine();
        String liczbaWierszy = bufR.readLine();
        String liczbaKolumn = bufR.readLine();
        int iloscWierszy = Integer.valueOf(liczbaWierszy);
        int iloscKolumn = Integer.valueOf(liczbaKolumn);
        double[][] tablica = new double[iloscWierszy][iloscKolumn];

        String w1;
        String wtrzy[][] = new String[tablica.length][iloscKolumn];
        for (int i = 0; i < wtrzy.length; i++) {
            w1 = bufR.readLine();
            String w2[] = w1.split(" ");
            for (int j = 0; j < wtrzy[i].length; j++) {
                wtrzy[i][j] = w2[j];
                wtrzy[i][j]=wtrzy[i][j].replaceAll(",",".");
            }
        }
        for (int i = 0; i <tablica.length; i++)
        {
            for (int j = 0; j <tablica.length; j++)
            {
                tablica[i][j]=Double.valueOf(wtrzy[i][j]);
            }
        }
        double suma =0;
        for(int i=0; i<tablica.length; i++)
        {
            for(int j=0; j<tablica[i].length; j++)
            {
                suma+=tablica[i][j];
            }
        }
        double srednia=suma/(iloscKolumn*iloscWierszy);
        System.out.print("Srednia wynosi:");
        System.out.print(String.format("%3.3f ", srednia));
        System.out.println();
    }

1

Fajnie, że sam doszedłeś do rozwiązania a nie sępiłeś o nie.

Osobiście zrobiłem to dla treningu używając Stream API więc wkleję może Cię zaciekawi (obsługa błędów / wydajność pominięte):

        File file = new File(getClass().getClassLoader().getResource("tst.txt").getFile());
        BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
        bufferedReader.readLine();
        String rows = bufferedReader.readLine();
        String cols = bufferedReader.readLine();
        int rowsNumber = Integer.valueOf(rows);
        int colsNumber = Integer.valueOf(cols);

        double sum = bufferedReader.lines()
                .flatMap(l -> Arrays.stream(l.split("\\s")))
                .map(s -> s.replaceAll(",", "."))
                .map(Double::parseDouble)
                .mapToDouble(d -> d)
                .sum();

        System.out.print("Sum:\t" + sum);
        System.out.print("Average:\t" + (sum / (rowsNumber * colsNumber)));

1 użytkowników online, w tym zalogowanych: 0, gości: 1