Autor rozwiązania: Maciej Muras

Plik z zadaniami można pobrać ze strony https://cke.gov.pl/images/_EGZAMIN_MATURALNY_OD_2015/Arkusze_egzaminacyjne/2015/formula_do_2014/MIN-R2_1P-152.pdf

Pobierz plik z danymi do zadania slowa.txt

Treść zadania:
Zadanie 4. Słowa binarne
W pliku slowa.txt zapisano 1000 słów zerojedynkowych o długościach od 2 do 25
znaków, w każdym wierszu po jednym słowie. Napisz program, który da odpowiedzi
do poniższych zadań. Odpowiedzi zapisz w pliku wynik4.txt, a każdą odpowiedź
poprzedź numerem zadania.
Blokiem w słowie nazywamy ciąg kolejnych takich samych znaków, którego nie można
wydłużyć. W słowie 100110001 mamy 5 bloków: 1, 00, 11, 000, 1.
Zadanie 4.1. (2 pkt)
Podaj, ile jest słów w pliku slowa.txt, w których liczba zer jest większa od liczby
jedynek.
Przykład:
Dla zestawu danych:
101011010011001100111
10001001
0001000
101010011100
000011
1111100
wynikiem jest liczba 3 (3 podkreślone słowa spełniają warunki zadania).

W celu rozwiązania zadania musimy należy wykonać następujące czynności:

  1. Wczytanie danych z pliku

Java oferuje wiele sposobów na wczytywanie danych z pliku, skupię się na najprostszym sposobie realizującym ten cel używając klasy Scanner (jeśli jesteś zainteresowany bardziej zaawansowanymi metodami to zapraszam np. na stronę http://www.maciejmuras.com/?page_id=96 ).

  1. Na początku musimy dodać importy klas:
    import java.io.*; – do obsługi min. plików
    import java.util.*; – zawiera min. Scanner oraz kolekcję Map
  2. W kolejnym kroku dodajemy obsługę wyjątku FileNotFoundException
    public static void main(String[] args) throws FileNotFoundException {
  3. Następnie deklarujemy i inicjalizujemy zmienne, kolekcje oraz obiekty używane w programie (opis przeznaczenia w dalszej części zadania).
String wiersz;
int zera = 0;
int wieksza_ilosc_zer = 0;
boolean czy_znaleziono_liczbe_z_2_blokow = false, drugi_blok = false;
int ile_liczb_z_2_blokow = 0;
int aktualne_maksimum = 0;
int dlugosc_bloku = 0;
int numer_wiersza_w_pliku=0;
Map <Integer, String> wiersze_z_najdluzszym_blokiem = new HashMap<>();
String tablica_0_1[];
Scanner odczyt = new Scanner(new File("slowa.txt")); 
zmienna odczyt klasy Scanner umożliwi nam dostęp do pliku.
while (odczyt.hasNextLine()) {

//za pomocą metody hasNextLine() sprawdzamy czy w pliku są jeszcze jakieś linie, metoda zwraca true jeśli w pliku jest jeszcze jakaś linia, a co za tym idzie pętla działa do czasu gdy w pliku tekstowy znajdują się linie 

wiersz = odczyt.nextLine(); // do zmiennej wiersz (typ String) wczytujemy linijkę z pliku testowego powiązanego ze zmienną odczyt
tablica_0_1 = wiersz.split(""); // split dzieli nam tekst wg podanego kryterium zwanego separatorem np. jeśli użyjemy spacji zmienna.split(" ") podzieli zdanie na pojedyncze słowa. Brak separatora dzieli tekst na pojedyncze znaki. wiersz.split("") dzieli tekst zawarty w zmiennej wiersz na znaki, które trafiają do kolejnych elementów tablicy tablica_0_1,  

// Z treści zadania A: Podaj, ile jest słów w pliku slowa.txt, w których liczba zer jest większa od liczby
// jedynek.

zera = 0; // w tej zmiennej przechowuję liczbę zer w wierszu
for (String a : tablica_0_1) { // pętla for each w kolejnych iteracjach przypisuje do zmiennej a zawartość kolejnych elementów tablicy tablica_0_1, pętla działa więc tyle razy ile elementów zawiera tablica
if (a.equals("0")) zera++; // jeśli zmienna a jest równa 0 zwiększ zmienną zera, czyli zliczamy ilość zer
}
if (zera > (tablica_0_1.length / 2)) wieksza_ilosc_zer++;
// zmienna wieksza_ilosc_zer przechowuje -zgodnie z treścią zadania - liczbę linii, w których mam więcej zer niż jedynek.
// tablica_0_1.length / 2 - oblicza połowę długości tablicy, jeśli zer jest więcej niż połowa wielkości tablicy to logicznym jest że jest ich więcej niż jedynek
// alternatywny zapis
if (zera > (tablica_0_1.length-zera)) // gdzie tablica_0_1.length-zera oblicza ilość jedynek

// ROZWIĄZANIE ZADANIA 4.1 zawarte jest w zmiennej zera 

//ZADANIE 4.2

Podaj, ile jest słów składających się z dokładnie dwóch niepustych bloków: pierwszego
składającego się samych zer i drugiego składającego się z samych jedynek

drugi_blok = false;
// zmienna drugi_blok przechowuje informacje typu boolean czy w analizowanym wierszu po początkowych zerach pojawiły się jedynki
czy_znaleziono_liczbe_z_2_blokow = false; 
// czy_znaleziono_liczbe_z_2_blokow - określa czy znaleziono ciąg cyfr zgodnych z wytycznymi w zadaniu tzn. taką gdzie na pierwszej pozycji mamy 0(lub większą liczbę zer) następnie do końca linii wyłącznie 1 (lub większą liczbę jedynek)
if (tablica_0_1[0].equals("0")) {
// tylko jeżeli pierwsza cyfra w słowie jest zerem sprawdzamy pozostałe warunki, w przeciwnym wypadku (jeśli na początku jest 1) słowo nie spełnia warunków


    for (String a : tablica_0_1) {

        if (a.equals("0")) {
//jeśli znajdziemy zero 
            if (drugi_blok == false) continue;
//sprawdźmy czy nie jesteśmy już drugim bloku składającym się z jedynek, jeśli nie przechodzimy do kolejnej iteracji przez continue
            else {
                czy_znaleziono_liczbe_z_2_blokow = false;
// w przeciwnym wypadku oznacza to że znaleźliśmy zero będąc po drugim bloku cyfr (jedynek), co jest niezgodne z założeniami punktu 4.2
                break;
// więc przerywamy pętle
            }
        } else {
// w przeciwnym wypadku odczytaliśmy jedynkę, więc...
            drugi_blok = true;
// jesteśmy w drugim bloku składającym się z jakiejś ilości jedynek
            czy_znaleziono_liczbe_z_2_blokow = true;
// na tym etapie spełnione są założenia zadania 4.2 więc możemy przypisać zmiennej wartość true
        }

    }
}
if (czy_znaleziono_liczbe_z_2_blokow) {
// jeśli po zakończeniu pętli zmienna czy_znaleziono_liczbe_z_2_blokow ma wartość true
    ile_liczb_z_2_blokow++;
// oznacza to że znaleźliśmy kolejną liczbę spełniającą warunki zdania, więc możemy zwiększyć zmienną ile_liczb_z_2_blokow
}

// ----------------------------------------- zadanie 4.3 -----------------------------------------
Zadanie 4.3. (5 pkt)
Podaj długość najdłuższego bloku złożonego z samych zer pojawiającego się w słowach
w pliku slowa.txt. Wypisz wszystkie słowa z tego pliku, które zawierają taki najdłuższy
blok złożony z samych zer.
Przykład:
Dla zestawu słów:
100010000100
001
000
10101001110000
000011
Wynikami są liczba 4 oraz pogrubione słowa. 

             dlugosc_bloku = 0; // zerujemy by nie dodawałam nam zer z końca ostatniego wiersza i początku kolejnego
            // pierwsza pętla szuka najdłuższego ciągu zer, informacja jest zawarta w zmiennej aktualne_maksimum
            for (String cyfra2:tablica_0_1){
                if (cyfra2.equals("0")) {
                    dlugosc_bloku++;
//jeśli znaleźliśmy zero to zwiększamy zmienną dlugosc_bloku
                    if (dlugosc_bloku ==aktualne_maksimum) wiersze_z_najdluzszym_blokiem.put(numer_wiersza_w_pliku, wiersz);
// jeśli dlugosc_bloku ==aktualne_maksimum umieszczamy w kolekcji map wartość wiersza z aktualnym najdłuższym blokiem
                    else if (dlugosc_bloku > aktualne_maksimum) {
// jeśli dlugosc_bloku > aktualne_maksimum
                        aktualne_maksimum = dlugosc_bloku;
// ustawiamy nowe aktualne_maksimum 
                        wiersze_z_najdluzszym_blokiem.clear();
// usuwamy wszystkie elementy z mapy  wiersze_z_najdluzszym_blokiem
                        wiersze_z_najdluzszym_blokiem.put(numer_wiersza_w_pliku, wiersz);
// dodajemy do mapy bieżący wiersz z najdłuższym blokiem zer 
                    }
                } else {
                    dlugosc_bloku = 0;
// w przeciwnym razie znaleźliśmy jedynkę, więc możemy wyzerować zmienną dlugosc_bloku (bo sprawdzamy największą ilość kolejnych zer a nie jedynek)
                }
            }
            numer_wiersza_w_pliku++;
// prze zakończeniem pętli zwiększamy o 1 liczbę określającą w którym miejscu pliku się znajdujemy
        } // zakończenie głównej pętli while odczytującej dane z pliku
        odczyt.close();
// pamiętajmy o zamykaniu pliku przez wyjściem z programu
        System.out.println("4.1: większa ilość zer jest w  "+wieksza_ilosc_zer+" wierszach\n4.2: " +
                ""+ile_liczb_z_2_blokow+" liczb z dwóch bloków \n4.3: Dlugosc najdłuższego bloku " +
                "to: "+aktualne_maksimum);
        System.out.println("wiersza z najdłużyszym blokiem zer to: "+wiersze_z_najdluzszym_blokiem.values());
//pozostaje wypisać wyniki dla wszystkich podpunktów
        }
    }
Analiza zadań maturalnych – 2015: Zadanie 4. Słowa binarne