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.