Strumienie, odczyt z pliku tekstowego do tablicy

Strumienie, odczyt z pliku tekstowego do tablicy
hdw3
  • Rejestracja:ponad 8 lat
  • Ostatnio:ponad 6 lat
  • Postów:30
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]
Kopiuj
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ć:

Kopiuj
     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)

edytowany 6x, ostatnio: hdw3
nie100sowny
  • Rejestracja:około 9 lat
  • Ostatnio:około 22 godziny
  • Lokalizacja:Kraków
  • Postów:402
1

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

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

"Gdy się nie wie, co się robi, to się dzieją takie rzeczy, że się nie wie, co się dzieje"
edytowany 2x, ostatnio: nie100sowny
hdw3
  • Rejestracja:ponad 8 lat
  • Ostatnio:ponad 6 lat
  • Postów:30
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:

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

edytowany 2x, ostatnio: hdw3
szweszwe
  • Rejestracja:ponad 11 lat
  • Ostatnio:6 dni
  • Lokalizacja:Kraków
  • Postów:1694
0

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

Kopiuj
for(int i=0; i<tablica.length; i++) {
   String[] line = bufR.readLine().split(" ");
   System.out.println(Arrays.toString(line));
   tablica[i] = line;
}
hdw3
  • Rejestracja:ponad 8 lat
  • Ostatnio:ponad 6 lat
  • Postów:30
0

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

Kopiuj
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:

Kopiuj
[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:

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

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

Kopiuj
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

szweszwe
  • Rejestracja:ponad 11 lat
  • Ostatnio:6 dni
  • Lokalizacja:Kraków
  • Postów:1694
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()

hdw3
  • Rejestracja:ponad 8 lat
  • Ostatnio:ponad 6 lat
  • Postów:30
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:

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

nie100sowny
  • Rejestracja:około 9 lat
  • Ostatnio:około 22 godziny
  • Lokalizacja:Kraków
  • Postów:402
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):

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

"Gdy się nie wie, co się robi, to się dzieją takie rzeczy, że się nie wie, co się dzieje"
edytowany 1x, ostatnio: nie100sowny

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.