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:
-
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 ).
- 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 - W kolejnym kroku dodajemy obsługę wyjątku FileNotFoundException
public static void main(String[] args) throws FileNotFoundException {
- 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 } }