Zobacz: Algorytmy sortujące: ich opisy i porównanie: http://www
Transkrypt
Zobacz: Algorytmy sortujące: ich opisy i porównanie: http://www
Zobacz: Algorytmy sortujące: ich opisy i porównanie: http://www.home.umk.pl/~abak/wdimat/s/Compare.html Program ma pobrać dane z pliku tekstowego: liczbę osób, oraz imiona i nazwiska wszystkich osób, następnie posortować dane osób alfabetycznie według nazwisk i zapisać wszystkie dane do nowego pliku tekstowego. public class BazaOsob { // dane umieszczę w tablicy B, zawierającej obiekty klasy Osoba public static void main(String[] args) { try { Scanner s = new Scanner(new File("osoby.txt")); int n=s.nextInt(); // z tego pliku będą czytane dane: imiona I nazwiska Osoba [] B = new Osoba[n]; // B to jest referencja do tablicy // coś jakby sznurek na którym w pamięci wisi cała tablica obiektów for (int i=0; i<n; i++) { B[i] = new Osoba(); // referencja do pojedynczego obiektu (sznurek na którym wisi obiekt) B[i].imie = s.next(); B[i].nazwisko = s.next(); System.out.print(i+" "+B[i].nazwisko+”, ” ); } System.out.println("\nPierwszy element "+B[0].nazwisko); System.out.println("Ostatni element "+B[n-1].nazwisko); System.out.println("\nJeszcze raz:"); for (Osoba b : B) System.out.println(b.nazwisko+" "+b.imie); // b jest iteratorem, „staje się” po kolei // każdym elementem tablicy B // Algorytm Sortowanie przez wstawianie (od razu na właściwe miejsce w tablicy) // dla wszystkich elementów poprzednich względem bieżącego j: // jeśli nazwisko_poprzednie > nazwisko_bieżące to zamień elementy miejscami for (int i=0; i<n; i++) { int j = i; while ((j>0) && (B[j-1].nazwisko.compareTo(B[j].nazwisko))>0) { Osoba c = B[j]; B[j] = B[j-1]; B[j-1] = c; j--; } } // porównywanie String-ów System.out.println("\nTeraz posortowane” ); for (Osoba b : B) System.out.println(b.nazwisko+" "+b.imie); PrintWriter pw = new PrintWriter(new File("naucz_sort.txt")); // zapis do pliku txt for (Osoba b : B) pw.println(b.nazwisko+" "+b.imie); // obiekt pw klasy PrintWriter jest pw.close(); // strumieniem tekstowym } catch (FileNotFoundException e) { System.out.println("brak pliku danych"); } } } class Osoba { public String imie, nazwisko; } Klasa Arrays ma zdefiniowane statyczne metody manipulacji elementami, np. sortowanie, wyszukiwanie binarne, max i min. Statyczne – tzn. można wywołać metodę bez tworzenia obiektu tej klasy, odwołując się tylko do nazwy klasy. Aby posortować tablicę A zmiennych prostych lub stringów, wystarczy wywołać: Arrays.sort(A); Jeżeli elementami tablicy B są obiekty, to przed automatycznym sortowaniem trzeba najpierw zdefiniować sposób porónywania obiektów: względem którego pola i jak je porównywać. W tym celu klasa opisująca elementy tablicy musi 1 implementować interfejs Comparable i nadpisać jego metodę compareTo(), na przykład: class Osoba implements Comparable <Osoba> public { String imie, nazwisko; public int compareTo(Osoba y) { return this.nazwisko.compareTo(y.nazwisko); } } Po czym można wywołać Arrays.sort(B), zamiast samemu żmudnie kodować algorytm sortujący. ---------------------------------------------------------------------------------------------------------------------------------------- W języku Java istnieją różne klasy kontenerów. Obiekt klasy kontenerowej służy do przechowywania wielu obiektów. Tablica jest najprostszym kontenerem, w którym elementy są dostępne przez indeks. Vector, List i ArrayList – to również klasy kontenerów, w których elemeny są dostępne przez indeks, ale rozmiar tych kontenerów może być dynamicznie zmieniany w razie zwiększenia lub zmniejszenia liczby elementów. Ponadto kontenery mają zdefiniowane metody dodawania i usuwania środkowych elementów i wiele innych metod, np.: • • • • • • • add(obiekt) – umieszcza nowy element na końcu listy add(int i, obiekt) – umieszcza nowy obiekt na i-tej pozycji (zwiekszając indeks następnych elementów o 1) get(int i) – zwraca obiekt z i-tej pozycji w listy set(int i, obiekt) - umieszcza element na i-tej pozycji listy, zastępując poprzednią zawartość pozycji remove(int i) – usuwa element z i-tej pozycji clear() – usuwa wszystkie elementy z tablicy size() – zwraca liczbę elementów listy Istnieje też w Javie klasa Collections, która ma zdefiniowane wiele metod zarządzania listami (List, ArrayList, Vector). Wykorzystując metody klasy Collections dla list, podobnie jak metody klasy Arrays dla tablic, można szybko sortować (algorytm MergeSort), wyszukiwać maksimum, minimum i podaną wartość (algorytm wyszukiwania binarnego). Metody klasy Collections, tak jak metody klasy Arrays, są statyczne, tzn. można je uruchomić nie tworząc obiektu klasy Collections. Przykład sortowania wektora B: Collections.sort(B); // klasa elementów wektora B musi implementować // interfejs Comparable i nadpisać metodę compareTo() Zwykłą tablicę i wektor można konwertować na listę i odwrotnie: 1 // deklaracja tablicy Osoba [] B = new Osoba[n]; // deklaracja wektora Vector <Osoba> B = new Vector <Osoba>(); // konwersja tablicy B na listę BL List BL = new ArrayList(Arrays.asList(B)); // konwersja wektora B na listę BL List <Osoba> BL = new ArrayList <Osoba>(B); // konwersja listy BL na tablicę B BL.toArray(B); // konwersja listy BL na wektor B Collections.copy(B, BL); Interfejs - jest abstrakcyjnym typem, zawiera tylko prototypy metod, bez ich definicji. Klasa która implementuje jakiś interfejs, musi nadpisać wszystkie jego metody. Klasa może implementować wiele interfejsów, ale dziedziczyć może tylko z 1 klasy bazowej. Problem ze strony 1 (wczytaj dane z pliku i posortuj) przy zastosowaniu ArrayList zamiast zwykłej tablicy obiektów. Z pliku danych usunęłam pierwszą daną: liczbę osób, bo nie potrzeba już określać rozmiaru kontenera danych. public class BazaOsob1 { public static void main(String[] args) { ArrayList <Osoba> B = new ArrayList <Osoba>(); // dane przechowywane w kontenerze klasy ArrayList try { Scanner s = new Scanner(new File("osoby.txt")); while (s.hasNext()) { Osoba b = new Osoba(); b.imie = s.next(); b.nazwisko = s.next(); B.add(b); } System.out.println("Wszystkich elementów jest "+B.size()); System.out.println("Pierwszy element "+B.get(0).nazwisko); System.out.println("Ostatni element "+B.get(B.size()-1).nazwisko); System.out.println("\nJeszcze raz:"); for (Osoba q : B) System.out.println(q.nazwisko+" "+q.imie); Collections.sort(B); // klasa porównywana musi implementować interfejs Comparable // i nadpisać jego metodę compareTo() System.out.println("\nTeraz posortowane”); for (Osoba q : B) System.out.println(q.nazwisko+" "+q.imie); } catch (FileNotFoundException e) { System.out.println("brak pliku danych"); } } } class Osoba implements Comparable <Osoba> { public String imie, nazwisko; public int compareTo(Osoba y) { return this.nazwisko.compareTo(y.nazwisko); } } Różnice między ArrayList a Vector: • Vector jest synchronizowany, a ArrayList nie. To znaczy że w programie wielowątkowym drugi wątek będzie automatycznie widział zmiany w wektorze dokonane przez pierwszy wątek, a ArrayListę trzeba będzie sobie odświeżyć. Jeśli twój program nie jest wielowątkowy, to po co przeznaczać czas i zasoby na synchronizację? wystarczy ArrayList. • Jeśli potrzebujesz dynamicznie powiększać rozmiar kontenera, pamietaj że: Vector domyślnie powiększa swój rozmiar dwukrotnie ArrayList – tylko o 50% Jeżeli potrzebujesz często przeglądać elementy oraz dodawać/ usuwać elementy z początku/ końca listy , to oba typy: Vector i ArrayList zrobią to równie szybko. Ale jeśli potrzebujesz często dodawać/usuwać elementy w środku listy, użyj klasy LinkedList zamiast tamtych dwóch, będzie szybciej.