Documente Academic
Documente Profesional
Documente Cultură
Algoritmi PDF
Algoritmi PDF
Analiza i proiectarea
algoritmilor
Curs, anul II Calculatoare, Tehnologia informaiei,
Ingineria sistemelor multimedia
Puncte de credit: 5
Cuprins (1)
Partea I Limbajul Java
Variabile i constante
Tablouri i matrici
Tratarea excepiilor
Operaii I/O
Crearea claselor
Interfee grafice
Fire de execuie
Colecii
2
Cuprins (2)
Partea II Analiza algoritmilor
Cuprins (3)
Partea III Proiectarea algoritmilor
Divide et impera
Greedy
Programare dinamic
Backtracking
Algoritmi genetici
Reele neuronale
Nota final
Nota laborator (NL) = 0,2*T1 + 0,2*T2 + 0,1*A + 0,5*C
Nota final = 0,5*NL + 0,5*E
Bibliografie de baz
[Knu00] Knuth D., Arta programrii calculatoarelor, Teora, 2000.
[Cor00] Cormen T., Leiserson C., Rivest R., Introducere n algoritmi, Agora, 2000.
[Giu04] Giumale C., Introducere n analiza algoritmilor, Polirom, 2004.
[Wai01] Waite M., Lafore R., Structuri de date i algoritmi n Java, Teora, 2001.
[Log07] Logoftu D., Algoritmi fundamentali n Java, Polirom, 2007.
[Tan07] Tanas ., Andrei ., Olaru C., Java de la 0 la expert, Polirom, 2007.
Introducere (1)
Introducere (2)
Eclipse http://www.eclipse.org
Java Builder
NetBeans
Introducere (3)
Cod surs
.java
Bytecode
Compilator
Java
.class
Java
Virtual
Machine
javac *.java
java *
9
Partea I
Limbajul Java
Limbajul Java
O aplicaie simpl:
class HelloWorld{
public static void main(String args[]){
System.out.println("Hello world");
}
}
11
Directivele de import;
Constructori i metode;
Convenii de nume
12
int i = 10;
float pi = 3.14f;
//Rezultat: w
//Rezultat: Hello
//Rezultat: 11
//Rezultat: true
//Rezultat: equal
16
//Rezultat: 0
//Rezultat: equal
//Rezultat: 7
//Rezultat: 5
18
int[] fibo =
int fibo[] =
int n = 10;
int fibo[] =
int fibo[] =
new int[10];
new int[10];
new int[n];
{0, 1, 1, 2, 3, 5, 8, 13, 21, 34};
fill permite umplerea tabloului sau a unei zone din tablou cu o anumit valoare:
int tab[] = new int[5];
Arrays.fill(tab, 7);
Arrays.fill(tab, 1, 3, 8);
equals compar dou tablouri returnnd true dac au toate elementele egale:
int a[] = {1,2,3,4};
int b[] = {1,2,3,4};
int c[] = {1,2,4,8};
System.out.println(Arrays.equals(a, b) ? "a==b" : "a!=b");
System.out.println(Arrays.equals(a, c) ? "a==c" : "a!=c");
//Rezultat: a==b
//Rezultat: a!=c
sort sorteaz elementele tabloului n ordine cresctoare folosind algoritmul Quicksort pentru tipuri primitive
respectiv Mergesort pentru tipuri referin:
int pTab[] = {9,6,2,1,5,3};
Arrays.sort(pTab,1,4);
Arrays.sort(pTab);
Integer rTab[] = new Integer[5];
for(int i=0, k=rTab.length; i<rTab.length; i++, k--)
rTab[i] = new Integer(k);
Arrays.sort(rTab);
//Rezultat: tab={7,7,7,7,7}
//Rezultat: tab={7,8,8,7,7}
//Rezultat: tab={9,1,2,6,5,3}
//Rezultat: tab={1,2,3,5,6,9}
//Rezultat : tab={5,4,3,2,1}
//Rezultat : tab={1,2,3,4,5}
binarySearch returneaz poziia elementului cutat n tablou sau o valoare negativ dac valoarea cutat
nu este gsit. Algoritmul folosit este cutarea binar, de aceea tabloul trebuie sortat nainte de apelul acestei
metode. Exemplu:
int tab[] = {5,4,1,7,3};
int v = Arrays.binarySearch(tab, 4);
Arrays.sort(tab);
v = Arrays.binarySearch(tab, 4);
//tablou nesortat
//Rezultat greit: -4
//Rezultat: tab={1,3,4,5,7}
//Rezultat corect: 2
20
//Rezultat afiat:
//1 2 3 4
//5 6 7 8 9
//10 11 12 13 14 15
22
//Rezultat : "a==b"
Variabile referin
//Rezultat: "a!=b"
//Rezultat : "a==b
//Rezultat: "a==b"
//Rezultat: "a==b"
23
canRead / canWrite returneaz true dac aplicaia poate citi / modifica fiierul;
list apelat pentru un director returneaz un tablou de tip String cu toate fiierele i
subdirectoarele din acel director. Exemplu:
File file = new File("e:\\algoritmi_curs");
String str[] = file.list();
for(int i=0; i<str.length; i++)
System.out.println(str[i]);
listFile apelat pentru un director returneaz un tablou de tip File cu toate fiierele i
subdirectoarele din acel director;
listRoots returneaz un tablou de tip File reprezentnd rdcinile sistemelor de fiiere
disponibile n sistem (ex.: "C:\\", "D:\\", "E:\\");
24
mkdirs creeaz un director nou, inclusiv directoarele inexistente care apar n cale
renameTo permite redenumirea fiierelor, returnnd true n caz de succes. Exemplu:
File file = new File("Algoritmi.pdf");
System.out.println(file.renameTo(new File("algoritmi_curs.pdf")));
25
//3.141592653589793
//3 - rotunjire la cel mai apropiat intreg
//3.0 - rotunjire in jos
//4.0 - rotunjire in sus
//8.0 - ridicare la putere
//3.0 - radical
//2.7182818284590455 - valoarea exponentiala
//2.718281828459045
//2 - minimul
//8 - maximul
//5 - valoarea absoluta
//1.0 - logaritmul natural
//valoare aleatoare subunitara
//1.0 - sinusul, exista si celelalte functii
//90.0 - conversie in grade
//3.141592653589793 - conv. in rad.
Aplicaii propuse
1.
2.
3.
4.
5.
6.
S se scrie un program care, prin intermediul clasei File, s permit navigarea n structura de directoare din sistem.
27
Dac nu apar excepii, blocul try execut toate instruciunile. Dac o instruciune
din blocul try genereaz o excepie, se caut blocul catch corespunztor,
trecnd peste restul instruciunilor din try. Dac exist un catch corespunztor,
se execut instruciunile din acel bloc catch. Dac nu este gsit un bloc catch
corespunztor, excepia este transmis mai departe n ierarhia apelant. Dac
excepia ajunge n vrful ierarhiei fr s fie tratat, programul afieaz un
mesaj de eroare i se ntrerupe.
28
Este posibil ignorarea excepiilor i transmiterea lor mai sus prin throws n
ierarhia apelant.
n exemplul urmtor, dac n metoda apare Exceptia1 sau Exceptia2, ea este
ignorat, transmis mai departe i tratat n metoda apelant main (ca n
exemplul precedent):
public void metoda() throws Exceptia1, Exceptia2 {
//instructuni care pot genera Exceptia1 si Exceptia2
}
public static void main(String[] args) {
try{
metoda();
}
catch(Exceptia1 e1){
//instructiunile care se executa daca apare Exceptia1
}
catch(Exceptia2 e2){
//instructiunile care se executa daca apare Exceptia2
}
finally{
//instructiunile care se executa indiferent ca apare sau nu o exceptie
}
}
29
Tratarea excepiei:
String str = "I'm a String!";
try {
int i = Integer.parseInt(str);
}
catch (NumberFormatException nfe) {
System.out.println("Conversia nu a fost posibila!");
}
Tratarea excepiei:
int tab[] = new int[10];
try {
tab[10] = 10;
}
catch (ArrayIndexOutOfBoundsException aioobe) {
System.out.println("Ati accesat un element inexistent!");
}
Fluxuri de caractere:
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str = null;
try {
str = br.readLine();
}
catch (IOException ioe) {
ioe.printStackTrace();
}
Fluxuri de octei:
DataInputStream dis = new DataInputStream(System.in);
String str = null;
try {
str = dis.readLine();
}
catch (IOException ioe) {
ioe.printStackTrace();
}
32
Fiind scrise prin metodele writeInt i writeFloat, valorile pot fi citite din fiier
folosind metodele readInt respectiv readFloat ale clasei DataInputStream
try{
FileInputStream fis = new FileInputStream("data.txt");
DataInputStream dis = new DataInputStream(fis);
System.out.println(dis.readInt());
System.out.println(dis.readFloat());
dis.close();
}
catch(IOException ioe){
ioe.printStackTrace();
}
35
36
37
2.
3.
S se implementeze un program care citete de la tastatur lungimea unui tablou de tip String
i elementele acestuia (numele studenilor din semigrup). Sortai n ordine alfabetic tabloul
(v. metoda sort a clasei Arrays). Atenie, irurile trebuie transformate dup citire astfel nct
toate literele s fie mici sau toate mari (v. toLowerCase sau toUpperCase din String).
4.
Modificai prima aplicaie propus astfel nct s citeasc i vrsta utilizatorului. Dac vrsta
introdus depete 100 s afieze mesajul "Eti btrn!", altfel s afieze "Eti tnr!";
5.
6.
S se implementeze un program care citete dintr-un fiier ntr-un tablou de tip String numele
studenilor din semigrup. Sortai n ordine alfabetic tabloul (v. metoda sort a clasei Arrays).
Atenie, irurile trebuie transformate dup citire astfel nct toate literele s fie mici sau toate
mari (v. toLowerCase sau toUpperCase din String).
7.
S se citeasc dintr-un fiier un tablou de valori ntregi i s se afieze pe ecran media lor
aritmetic. Separarea valorilor de pe linii se va face prin clasa StringTokenizer prezentat
anterior.
8.
Internaionalizare i naionalizare
Java ofer suportul prin numeroase clase pentru
internaionalizarea i naionalizarea aplicaiilor
Clasa Locale
Locale locale = Locale.getDefault();
System.out.println(locale.getCountry());
System.out.println(locale.getDisplayCountry());
System.out.println(locale.getDisplayCountry(Locale.FRANCE));
System.out.println(locale.getDisplayLanguage());
System.out.println(locale.getDisplayLanguage(Locale.FRANCE));
System.out.println(locale.getDisplayName());
System.out.println(locale.getLanguage());
Locale g = Locale.GERMANY;
System.out.println(g.getLanguage());
//RO
//Romnia
//Roumanie
//romn
//roumain
//romn (Romnia)
//ro
//de
Clasa NumberFormat
System.out.println(NumberFormat.getInstance(locale).format(12.3));
System.out.println(NumberFormat.getCurrencyInstance(locale).format(6.8));
//12,3
//6,80 LEI
Clasa DateFormat
Date date = new Date(2009-1900, 8-1, 31);
System.out.println(DateFormat.getDateInstance(0, locale).format(date));
System.out.println(DateFormat.getDateInstance(2, locale).format(date));
//Y-1900, M-1, D
//31 august 2009
//31.08.2009
39
Definiia unei clase trebuie s conin cuvntul cheie class, numele clasei i corpul clasei.
Opional, nainte de cuvntul class pot fi folosii modificatorii public (clasa este vizibil n
toate pachetele), abstract (v. clase abstracte) sau final (clasa nu poate fi derivat).
Exemplu:
class Person {
private String name;
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
}
Variabile membru;
Constructori;
Metode.
Variabilele i metodele private pot fi accesate doar n cadrul clasei n care s-au declarat;
Variabilele i metodele protejate pot fi accesate n interiorul clasei, al subclaselor (v. motenirea) sau
n pachetul (package) n care au fost declarate;
Variabilele i metodele publice pot fi accesate oriunde;
Tipul de acces este implicit protejat (dac nu se precizeaz).
Variabile private;
Set de metode publice care s permit accesarea variabilelor private.
40
package person;
//Eroare!
//Eroare!
//Eroare!
41
package main;
import person.Person;
public class Main {
public static void main(String[] args) {
Person p = new Person();
}
}
//Eroare!
42
package main;
import person.Person;
public class Main {
public static void main(String[] args) {
Person p = new Person();
p.name = "Popescu";
p.setName("Popescu");
p.setAddress("Str. N. Balcescu, Nr. 5");
p.setAge(103);
System.out.println("Numele: " + p.getName());
System.out.println("Adresa: " + p.getAddress());
System.out.println("Varsta: " + p.getAge());
}
}
//Eroare!
//Eroare!
//Eroare!
//Eroare!
//Eroare!
//Eroare!
43
package person;
44
//Pop
//Sibiu
//103
//Rus
//Avrig
//98
46
Toate clasele Java, cu excepia interfeelor, sunt subclase ale clasei rdcin
Object;
Procesul prin care o clas nou refolosete o clas veche se numete motenire;
O clas, numit clas derivat, poate moteni variabilele i metodele unei alte
clase, numit clas de baz;
Derivarea unei clase n Java se face prin cuvntul cheie extends urmat de
numele clasei de baz;
Constructorii clasei derivate pot folosi printr-un apel super constructorii clasei
de baz pentru iniializarea variabilelor motenite;
//98
48
50
2.
3.
4.
5.
51
O clas trebuie declarat abstract dac conine cel puin o metod abstract.
Metodele abstracte sunt declarate fr implementare urmnd ca ele s fie
implementate n clasele derivate. O clas abstract nu poate fi instaniat.
Exemplu:
public abstract class Product {
private double price;
public Product(double price) {
this.price = price;
}
public abstract double computeFinalPrice();
public void setPrice(double price){
this.price = price;
}
public double getPrice(){
return price;
}
}
public class Book extends Product {
public Book(double price) {
super(price);
}
public double computeFinalPrice(){
return getPrice() + (9*getPrice())/100;
}
}
//TVA=19%
52
//TVA=19%
//TVA=9%
54
55
58
Definii clasa Person cu cmpurile name, address i age. Definii clasa Student
derivat din clasa Person avnd cmpul suplimentar grade (medie). Introducei
dintr-un fiier student.txt numrul de studeni din semigrup urmat de datele lor,
ntr-un tablou. Sortai i afiai studenii n ordinea cresctoare a mediei.
2.
Definii clasa Person cu cmpurile name, address i age. Definii clasa Teacher
derivat din clasa Person avnd cmpul suplimentar courses (nr. cursuri).
Introducei dintr-un fiier teacher.txt numrul de profesori din acest semestru
urmat de datele lor, ntr-un tablou. Sortai i afiai profesorii n ordinea cresctoare
a numrului de cursuri predate.
3.
4.
Definii clasa Product cu cmpul price (pre). Definii clasa Book (carte) derivat
din clasa Product avnd cmpurile suplimentare title, author i publisher
(editor). Introducei dintr-un fiier book.txt numrul de cri urmat de datele lor,
ntr-un tablou. Sortai i afiai crile n ordinea cresctoare a preului.
5.
6.
59
Partajarea datelor de ctre obiectele unei clase poate fi realizat prin intermediul membrilor
statici ai clasei respective.
n timp ce variabilele obinuite (non-statice) aparin instanelor clasei (obiectelor),
variabilele declarate statice aparin clasei i sunt partajate de ctre toate obiectele acesteia.
Unei variabile statice i se aloc memorie o singur dat, la prima instaniere a clasei. La
urmtoarele instanieri ale clasei variabilei statice nu i se mai aloc memorie, dar toate
obiectele clasei pot accesa aceeai variabil static, alocat la prima instaniere.
Metodele statice pot fi apelate fr instanierea clasei.
Metodele statice nu pot utiliza variabile i metode non-statice.
Un exemplu de utilizare a unei variabile statice este contorizarea obiectelor instaniate
dintr-o clas:
public class Person {
private String name;
static int counter;
public Person(String name) {
this.name = name;
counter++;
System.out.println(counter + " persoane.");
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
}
//"1 persoane."
//"2 persoane."
60
//"1
//"2
//"3
//"4
persoane."
persoane."
persoane."
persoane."
61
//"1 persoane."
//"2 persoane."
//"3 persoane."
//"4 persoane.
//Eroare!
//4
62
" + p1.getAge());
" + p2.getAge());
//"Pop, 61"
//"Pop, 61"
" + p1.getAge());
" + p2.getAge());
//"Pop, 62"
//"Pop, 62"
" + p1.getAge());
" + p2.getAge());
//"Rus, 62"
//"Rus, 62"
" + p1.getAge());
" + p2.getAge());
//"Lup, 53"
//"Rus, 62"
" + p1.getAge());
" + p2.getAge());
//"Lup, 54"
//"Rus, 62"
63
" + p1.getAge());
" + p2.getAge());
//"Pop, 61"
//"Pop, 61"
" + p1.getAge());
" + p2.getAge());
//"Pop, 62"
//"Pop, 61"
" + p1.getAge());
" + p2.getAge());
//"Pop, 62"
//"Rus, 61"
64
void this_windowClosing(WindowEvent e) {
System.exit(0);
//inchiderea aplicatiei
}
void addButton_actionPerformed(ActionEvent e) {
studentList.add(studentTextField.getText());
studentTextField.setText("");
//stergere
}
}
67
void this_windowClosing(WindowEvent e) {
System.exit(0);
//inchiderea aplicatiei
}
void addButton_actionPerformed(ActionEvent e) {
studentList.add(studentTextField.getText());
studentTextField.setText("");
//stergere
studentTextField.requestFocus();
}
void studentTextField_keyPressed(KeyEvent e) {
if(e.getKeyCode()==e.VK_ENTER)
addButton_actionPerformed(new ActionEvent(this, 0, null));
}
}
69
Constructori:
BorderLayout() fr distan ntre componente;
BorderLayout(int hgap, int vgap) primete ca parametri
distanele orizontale i verticale dintre componente.
71
72
Constructori:
GridLayout() creeaz o singur linie cu cte o coloan
pentru fiecare component adugat, fr distan ntre
componente;
public GridFrame() {
this.setSize(400, 220);
this.setTitle("GridLayout");
this.setLayout(gLayout);
this.setBackground(new Color(240, 240, 240));
this.add(firstButton);
this.add(secondButton);
this.add(thirdButton);
this.add(fourthButton);
this.add(emptyPanel);
this.add(fifthButton);
show();
}
73
First Button:
gridy = 0,
gridx = 0 (celula [0,0])
gridwidth = 2, gridheight = 1 (dou coloane, o linie)
weightx = 0.6 (0.6 din extraspaiul orizontal)
weighty = 0.0 (0.0 din extraspaiul vertical)
Second Button:
gridy = 0, gridx = 2 (celula [0,2])
gridwidth = 2, gridheight = 1 (dou coloane, o linie)
weightx = 0.3 (0.3 din extraspaiul orizontal)
weighty = 0.0 (0.0 din extraspaiul vertical)
Third Button:
gridy = 1, gridx = 0 (celula [1,0])
gridwidth = 4, gridheight = 1 (patru coloane, o linie)
weightx = 0.0 (0.0 din extraspaiul orizontal)
weighty = 0.3 (0.3 din extraspaiul vertical)
Fourth Button:
gridy = 2, gridx = 0 (celula [2,0])
gridwidth = 1, gridheight = 3 (o coloan, trei linii)
weightx = 0.0 (0.0 din extraspaiul orizontal)
weighty = 0.3 (0.3 din extraspaiul vertical)
Fifth Button:
gridy = 2, gridx = 1 (celula [2,1])
gridwidth = 3, gridheight = 2 (trei coloane, dou linii)
weightx = 0.6 (0.6 din extraspaiul orizontal)
weighty = 0.6 (0.6 din extraspaiul vertical)
Last Button:
gridy = 4, gridx = 1 (celula [4,1])
gridwidth = 3, gridheight = 1 (trei coloane, o linie)
weightx = 0.6 (0.6 din extraspaiul orizontal)
74
weighty = 0.3 (0.3 din extraspaiul vertical)
}
public static void main(String[] args) {
new GridBagFrame();
}
}
75
76
77
2.
3.
4.
5.
Firul de execuie primar este metoda main i atunci cnd acesta se termin, se
ncheie i programul.
Fiecare fir de execuie are o prioritate care poate lua valori de la 1 (prioritate
mic) la 10 (prioritate maxim). Firele cu prioritate mare sunt avantajate la
comutare, ele primesc mai des controlul procesorului.
Pentru implementarea unui fir de execuie n Java, se poate extinde clasa
Thread. Deoarece Java nu accept motenirea multipl, n cazul n care a fost
deja extins o clas, pentru crearea unui fir de execuie trebuie implementat
interfaa Runnable. Indiferent de metoda utilizat, se suprascrie metoda run
care trebuie s conin instruciunile firului.
Aplicaia urmtoare pornete dou fire de execuie: unul pentru afiarea
numerelor i cellalt pentru afiarea literelor. Pentru a observa diferenele dintre
cele dou metode de implementare, firul de execuie Numbers extinde clasa
Thread, n timp ce Letters implementeaz interfaa Runnable.
79
80
82
void paint(){
Graphics gbuffer = buffer.getGraphics();
//se deseneaza mai intai in buffer (tehnica Double Buffering)
gbuffer.setColor(Color.white);
gbuffer.fillRect(0, 0, getSize().width, getSize().height);
gbuffer.setColor(ball.getColor());
gbuffer.fillOval(ball.getPX(), ball.getPY(), ball.getSize(), ball.getSize());
paint(gbuffer);
//se copiaza imaginea din buffer pe fereastra (tehnica Double Buffering)
Graphics g = getGraphics();
g.drawImage(buffer, 0, 0, getSize().width, getSize().height, 0, 0, getSize().width, getSize().height, this);
}
void this_windowClosing(WindowEvent e) {
System.exit(0);
}
public static void main(String[] args){
new MyFrame();
}
}
83
85
2.
Modificarea aplicaiei astfel nct s permit pornirea mai multor mingi simultan.
3.
86
Clasa Vector s-a pstrat pentru compatibilitate cu versiuni JDK mai vechi de 1.2.
Exemple
Vector vector = new Vector();
vector.addElement(new Integer(1));
vector.add(new Integer(3));
vector.insertElementAt(new Integer(5), 1);
vector.setElementAt(new Integer(2), 1);
//vector
//vector
//vector
//vector
//vector
gol
= {1}
= {1, 3}
= {1, 5, 3}
= {1, 2, 3}
//lista goala
//list = {1}
//list = {1, 3}
//list = {1, 5, 3}
//list = {1, 2, 3}
87
Exemple:
Stack stack = new Stack();
//stiva goala
System.out.println(stack.empty());
//true
stack.push(new Integer(1));
//stack = {1}
stack.push(new Integer(2));
//stack = {1, 2}
stack.push(new Integer(3));
//stack = {1, 2, 3}
System.out.println(stack.search(new Integer(3))); //1
System.out.println(stack.search(new Integer(2))); //2
System.out.println(stack.empty());
//false
System.out.println(stack.pop());
//3, stack = {1, 2}
System.out.println(stack.peek());
//2, stack = {1, 2}
System.out.println(stack.pop());
//2, stack = {1}
System.out.println(stack.pop());
//1, stiva goala
System.out.println(stack.empty());
//true
88
//stiva goala
//stack = {1}
//stack = {1, 2}
//stack = {1, 2, 3}
//3, stack = {1, 2}
//2, stack = {1, 2}
//2, stack = {1}
//1, stiva goala
//coada goala
//queue = {1}
//queue = {2, 1}
//queue = {3, 2, 1}
//1, queue = {3, 2}
//2, queue = {3}
//3, coada goala
89
//hs
//hs
//hs
//hs
//hs
=
=
=
=
=
{}
{1}
{2, 1}
{2, 4, 1}
{2, 4, 1}
//ts = {1, 2, 4}
//ts = {1, 2, 3, 4}
90
91
92
93
Exemplu:
Anglia
Franta
Germania
Romania
94
2.
Definii clasa Course cu cmpurile title, teacher (profesor), credits (nr. credite) i
year (an de studiu). Introducei de la tastatur cinci obiecte de tip Course ntr-un
TreeSet i afiai cursul cu cel mai mic numr de credite.
3.
Definii clasa Course cu cmpurile title, teacher (profesor), credits (nr. credite) i
year (an de studiu). Introducei de la tastatur cinci obiecte de tip Course ntr-un
TreeSet i afiai cursul cu cel mai mare numr de credite.
4.
Definii clasa Course cu cmpurile title, teacher (profesor), credits (nr. credite) i
year (an de studiu). Introducei de la tastatur cinci obiecte de tip Course ntr-un
TreeSet i afiai-le n ordinea descresctoare a numrului de credite.
5.
Definii clasa Course cu cmpurile title, teacher (profesor), credits (nr. credite) i
year (an de studiu). Introducei de la tastatur cinci obiecte de tip Course ntr-un
TreeSet i afiai-le n ordinea cresctoare a anului de studiu.
6.
Definii clasa Course cu cmpurile title, teacher (profesor), credits (nr. credite) i
year (an de studiu). Introducei de la tastatur cinci obiecte de tip Course ntr-un
TreeSet i afiai-le n ordinea alfabetic a titlului.
7.
Definii clasa Course cu cmpurile title, teacher (profesor), credits (nr. credite) i
year (an de studiu). Introducei de la tastatur cinci obiecte de tip Course ntr-un
TreeSet i afiai-le n ordinea alfabetic a profesorului.
95
96
Partea II
Analiza algoritmilor
Analiza algoritmilor
n0
n0
n0
tim c
12 + 2 2 + ... + n 2 =
n(n + 1)(2n + 1) 1 3 1 2 1
= n + n + n
6
3
2
6
(1)
Rezult c
12 + 2 2 + ... + n 2 = O(n 4 )
(2)
12 + 2 2 + ... + n 2 = O(n 3 )
(3)
1
12 + 2 2 + ... + n 2 = n 3 + O(n 2 )
3
(4)
105
O(1)
O(log n)
O(n)
O(n log n)
O(n2)
O(np)
O(an)
106
2n
+ 4 2n
4) 2 n 2 + n ln n
5) n k + n + n k ln n
6) 1 + 2 + ... + n
7) 12 + 2 2 + ... + n 2
8) 13 + 2 3 + ... + n 3
9) 1 2 + 2 3 + ... + n (n + 1)
10) 12 + 3 2 + ... + (2n 1) 2
107
108
a = b logb a
log c (ab) = log c a + log c b
log b a n = n log b a
log c a
log b a =
log c b
log b a =
1
log a b
log b a log a b = 1
log b a = log b c log c a
c
= log b c log b a
a
1
log b = log b a
a
a logb n = n log b a
log b
109
n
T ( n) = a T + f ( n)
b
unde a1, b>1, iar f(n) este o funcie dat.
Teorema master. Fie a1 i b>1 constante, f(n) o funcie i T(n) definit pe
ntregii nenegativi prin recurena
n
T ( n) = a T + f ( n)
b
atunci T(n) poate fi delimitat asimptotic dup cum urmeaz:
1. dac f (n) = O(n logb a ), > 0 T (n) = (n logb a )
2. dac f (n) = (n logb a ) T (n) = (n logb a lg n)
n
3. dac f (n) = (n logb a + ), > 0 i af cf (n), c < 1 i n suficient de mari T (n) = ( f (n)).
b
110
n
S considerm T (n) = 9 T + n
3
Pentru aceast recuren a=9, b=3, f(n)=n, astfel
n log b a = n log 3 9 = n 2
log 9
) = O(n), = 1,
Deoarece f (n) = O(n
aplicnd cazul 1 al teoremei master,
3
T (n) = (n log3 9 ) = (n 2 )
111
1. n lg n O(n1 ), > 0
2. n lg n (n)
3. n lg n (n1+ ), > 0 (ex. = 0.01, n1.01 > n lg n)
Vom folosi n continuare metoda iteraiei pentru rezolvarea
acestei recurene.
112
2 n n
n
n
2T = 22T + lg = 2 2 T 2
2
2
2 2 2
+ n lg
2
n n
n
n
n
n
2 2 T 2 = 2 2 2T 3 + 2 lg 2 = 2 3 T 3 + n lg 2
2
2
2
2
2 2
n
n
n
2 q 1 T q 1 = 2 q T q + n lg q 1
2
2
2
2
= n q = lg n
q
2
113
lg n
T (1) +
lg n 1
n lg
k =0
T ( n) = 2
n
2k
lg n 1
lg n
(1) + n lg n lg 2 k
k =0
lg n 1
T (n) = n (1) + n lg n lg n n lg 2 k
lg 2
k =0
lg n 1
T (n) = n (1) + n lg n n k
1
k =0
n(n 1)
k
=
2
k =0
n 1
lg n 1
k =
k =0
lg n (lg n 1)
2
n lg n (lg n 1)
T (n) = n + n lg 2 n
T (n) = n lg 2 n
114
115
k n-1, m X[n].
Dac k=0, algoritmul se ncheie.
Dac X[k]m, mergei la pasul 5.
m X[k].
Decrementai k cu 1 i revenii la pasul 2.
Pasul Cost
Nr. execuii
1.
c1
2.
c2
3.
c3
n-1
4.
c4
5.
c5
n-1
X[1]>X[2]>X[3]
X[1]>X[3]>X[2]
X[2]>X[1]>X[3]
X[2]>X[3]>X[1]
X[3]>X[1]>X[2]
X[3]>X[2]>X[1]
0
118
An = k p nk
k
Cazul mediu:
c1 + c2n + c3(n-1) + c4ln n + c5(n-1) =
(c2+c3+c5)n + c4ln n + (c1-c3-c5) = an + b ln n + c = (n)
120
Cost
c1
c2
c3
Execuii
1
n
n-1
1 + 2 + ... + n n + 1
=
n
2
deci complexitatea n cazul mediu este tot (n).
122
Cost
c1
c2
Execuii
1
C+1-S
c3
c45
C-S
n log b a = n log 2 1 = n 0 = 1
deci putem aplica cazul 2 al teoremei master. Prin urmare,
T (n) = (n logb a lg n) = (n 0 lg n) = (lg n)
Astfel, n cazul cel mai defavorabil, C=(lg n) iar complexitatea
temporal este:
(c2+c3+c45)(lg n) + (c1+c2) = (lg n).
124
sortat
nesortat
Cost
c1
Execuii
n
k X[j]
c2
n-1
i j-1
c3
n-1
c4
X[i+1] X[i]
c5
(t
1)
i i-1
c6
(t
1)
c7
n-1
for j 2 to n do
X[i+1] k
j =2
n
j =2
n
j =2
126
t
j =2
= n 1
(t
j =2
1) = 0
c1n + c2 (n 1) + c3 (n 1) + c4 (n 1) + c7 (n 1) =
(c1 + c2 + c3 + c4 + c7 )n (c2 + c3 + c4 + c7 ) = an + b = (n)
127
j =2
j =2
t j = j =
n
(t j 1) =
j =2
n(n + 1)
1
2
n(n + 1)
n(n 1)
1 (n 1) =
2
2
n(n 1)
n(n 1)
n(n + 1)
1 + c 5
c1 n + c 2 (n 1) + c3 (n 1) + c 4
+ c6
+ c7 (n 1) =
2
2
2
c 4 c5 c 6
c 4 c5 c 6 2
+
+
n
+
c
+
c
+
c
+
+
c
1
2
3
7 n (c 2 + c 3 + c 4 + c 7 ) =
2 2
2 2 2
2
an 2 + bn + c = (n 2 )
128
2
2
2
4
j =2
j =2
n
n2 + n 2
n 2 3n + 2
(t j 1) =
( n 1) =
4
4
j =2
n
min
sortat
nesortat
SELSORT1 (X)
for i 1 to n-1 do
min i
for j i+1 to n do
if X[j] < X[min] then
min j
X[i] X[min]
130
SELSORT2 (X)
for i 1 to n-1 do
for j i+1 to n do
if X[j] < X[i] then
X[i] X[j]
n(n 1)
C = (n 1) + (n 2) + ... + 1 =
= ( n 2 )
2
131
BUBBLESORT1 (X)
n X.size
for i 1 to n do
for j 1 to n-1 do
if X[j] > X[j+1] then
X[j] X[j+1]
C = n(n 1) = (n 2 )
132
BUBBLESORT2 (X)
n X.size
for i 1 to n-1 do
for j 1 to n-i do
if X[j] > X[j+1] then
X[j] X[j+1]
C = (n 1) + (n 2) + ... + 1 =
n( n 1)
= ( n 2 )
2
133
BUBBLESORT3 (X)
n X.size
for i 1 to n-1 do
for j n-1 downto i do
if X[j] > X[j+1] then
X[j] X[j+1]
C = (n 1) + (n 2) + ... + 1 =
n(n 1)
= ( n 2 )
2
134
C = ( n 1) + ( n 2) + ... + 1 =
n(n 1)
= ( n 2 )
2
135
137
n log b a = n log 2 2 = n1 = n
2
2
unde T(1)=(1), iar (n)+(1)+(n)=(n), deci obinem recurena
n 1
T ( n) = 2T
+ ( n)
2
139
n 1
n 1
+ n 1 = 2 2 T n 2 3 + 21 n 1 1
2T
= 22T 2
2
2
2
2
2
n3
2
n 3
+ n 3 = 2 3 T n 7 + 2 2 n 3
2 2 T 2 = 2 2 2T 2
2
3
2
2
2
2
2
2
q 1
q
q 1
+ 1
+ 1
q 1 n 2
q n 2 + 1
q 1 n 2
=
+
2 T
2
T
2
q 1
q
q 1
2
2
2
140
n 2q + 1
q +1
=
1
2
= n + 1 q + 1 = lg(n + 1) q = lg(n + 1) 1
q
2
Astfel, obinem:
lg( n +1) 1
k =1
T ( n) = 2
lg( n +1) 1
(1) +
k 1 n 2 k 1 + 1
2
k
lg( n +1) 1
( n)
k =1
T (n) = (n + n lg(n + 1) n )
T (n) = (n lg n)
141
142
143
Funcii de dispersie
Mapeaz o cheie k ntr-una din cele m locaii ale tabelei de dispersie
Metoda diviziunii
h( k ) = k mod m
Metoda nmulirii
Dispersia universal
r
h(k ) = ai k i mod m,
i =0
K (chei)
k4
k2
k3
k3
k4
147
h( k , i ) = h (k ) + c1i + c 2 i 2 mod m,
149
Exerciii [Cor00]
1.
2.
150
Dac orice nod din arbore poate avea cel mult doi fii, atunci arborele se
numete arbore binar.
Exemplu:
6
3
2
7
5
151
//cheia
//alte informatii
//fiul stang
//fiul drept
//parintele
152
6
3
2
7
5
Inserarea nodului 4:
6
3
2
7
5
4
153
//nodul radacina
public BinaryTree() {
insert(new Node(7));
insert(new Node(1));
insert(new Node(5));
}
154
155
Cutarea returneaz nodul avnd cheia k dac exist sau NULL n caz contrar.
Cutarea recursiv
CAUTA_REC (x, k)
if x=NULL or k=x.cheie then
return x
if k<x.cheie then
return CAUTA_REC(x.st, k)
else
return CAUTA_REC(x.dr, k)
Cutarea iterativ (de obicei mai eficient dect varianta recursiv)
CAUTA_IT (x, k)
while xNULL and kx.cheie do
if k<x.cheie then
x x.st
else
x x.dr
return x
156
6
3
7
5
6
3
2
7
5
8
157
Dac x are subarbore drept, atunci succesorul lui x este nodul cu cheia
minim din acest subarbore. n exemplul anterior, succesorul lui 3 este 5.
Dac x nu are fiu drept, atunci succesorul lui x se determin traversnd
arborele de la x n sus pn cnd se ntlnete un nod care este fiu stng,
printele acelui nod fiind succesorul lui x. n exemplul anterior, succesorul
lui 5 este 6.
SUCCESOR (x)
if x.drNULL then
return MINIM (x.dr)
y x.p
while yNULL and x=y.dr do
xy
y y.p
return y
6
3
2
7
5
8
158
12
10
16
15
20
13
18
16
6
3
23
12
10
20
13
18
23
7
7
159
5
3
12
16
5
20
13
10
15
18
3
23
12
20
13
10
18
23
7
7
5
3
12
10
15
20
13
18
16
5
3
23
12
10
20
13
18
23
6
7
160
n
T ( n) = T + (1)
2
rezolvat deja pentru algoritmul de cutare binar.
Dac arborele binar este degenerat (ex. lan liniar de n noduri), atunci
timpul consumat n cazul cel mai defavorabil este (n).
Operaiile INORDINE, PREORDINE i POSTORDINE au nevoie de un
timp (n) pentru traversarea unui arbore binar de cutare cu n noduri.
162
2.
3.
4.
5.
6.
S se implementeze n clasa BinaryTree algoritmul de tergere a unui nod din arborele binar de
cutare.
7.
S se modifice clasa Node i operaiile implementate n clasa BinaryTree astfel nct cheia s
fie numele studentului.
8.
S se rezolve prin metoda iteraiei recurena aferent operaiilor de baz (inserare, cutare,
minim, maxim, succesor i tergere) pe un arbore binar de cutare echilibrat cu n noduri.
163
orice nod dintr-un heap minimizant trebuie s aib o cheie mai mic (sau egal)
dect oricare dintre fiii si.
orice nod dintr-un heap maximizant trebuie s aib o cheie mai mare (sau egal)
dect oricare dintre fiii si.
34
27
42
53
49
5
6
5
34
27
42
53
49
Heap-ul permite selecia rapid a elementului cu cheie minim sau maxim (care
este chiar rdcina), operaie realizat n O(1).
Heap-ul binar este slab ordonat n raport cu arborele binar de cutare, de aceea,
traversarea nodurilor n ordine este dificil.
164
34
27
34
27
42
53
49
42
53
49
34
34
42
53
49
27
42
53
49
27
165
3
1
27
1
34
2
42
4
5
3
53
5
49
6
5
1
34
5
3
2
27
7
42
4
53
5
49
6
34
27
3
2
42
4
53
5
49
6
167
EXTRAGE (A)
min A[1]
A[1] A[A.heapsize]
A.heapsize A.heapsize-1
RECONSTITUIE (A, 1)
return min
168
HEAPSORT (A)
CONSTRUIESTE (A)
for i A.size downto 2 do
A[1] A[i]
A.heapsize A.heapsize-1
RECONSTITUIE (A, 1)
170
k
tim c pentru orice x subunitar k x =
k =0
(1 x )2
lg n
k
n
1
2
Astfel rezult c O n k +1 = O k = O
2
2
2
2
1
k
=
0
k =0 2
2
k
= O ( n)
Dou vrfuri se numesc adiacente dac sunt conectate direct printr-o muchie.
Un graf se numete conex dac exist cel puin un drum ntre toate vrfurile.
A
a
D
f
C
d
A
a
g
e
D
f
175
1 dac (i, j ) E ,
aij =
0 altfel.
0
3
177
Listele de adiacen
2
3
Graf orientat
2
1
2
2
1
5
345
4
35
24
Listele de adiacen
3
5
1
2
3
4
5
1
2
3
4
5
25
34
4
5
2
Matricea de adiacen
1
Matricea de adiacen
1
179
1
15
12
17
Listele de adiacen
26
18
29
21
Graf orientat
1
15
12
17
21
2/12
1/12
2/26
2/18
1/15
5/15
3/26 4/18 5/17
4/29
3/29 5/21
2/17 4/21
Listele de adiacen
26
18
29
1
2
3
4
5
1
2
3
4
5
2/12 5/15
3/26 4/18
4/29
5/21
2/17
Matricea de adiacen
1
12
15
12
26
18
17
26
29
18
29
21
15
17
21
Matricea de adiacen
1
12
15
26
18
29
21
17
180
181
182
EXPLORARE (u)
u.c GRI
PRINT (u.i)
u.d t t+1
foreach v A[u] do
if v.c=ALB then
v.p u
EXPLORARE (v)
u.c NEGRU
u.f t t+1
185
s=surs, t=int/target
H=heuristic
Q=openset
C=closedset
188
2.
3.
Partea III
Proiectarea algoritmilor
191
192
Exemplu (n=2)
A
AB
A
AC
BC
194
2T (n 1) = 2 (2T ( n 2) + 1) = 2 2 T ( n 2) + 21
2 2 T ( n 2) = 2 2 (2T (n 3) + 1) = 2 3 T ( n 3) + 2 2
2 q 1 T (n q + 1) = 2 q T (n q ) + 2 q 1
T ( n ) = 2 T ( 0) + 2 k
n
k =0
n 1
n 1
T ( n) = 2 0 + 2 = 2 k
n
k =0
k =0
tim c
x n +1 1
x =
x 1
k =0
n
Rezult astfel c
2n 1
T ( n) =
= 2n 1
2 1
Aplicaii
1.
2.
3.
GREEDY (C)
S
while C do
x BEST (C)
C C-{x}
if FEASIBLE (S U {x}) then
S S U {x}
198
g
i =1
G < gj
j =1
g i , pentru i = 1, k
k
soluia fiind
G g i , pentru k + 1
i =1
Frecven
45
13
12
16
000
001
010
011
100
101
101
100
111
1101
1100
Dac folosim un cod binar de lungime fix, avem nevoie de trei bii pentru a
reprezenta ase caractere (a=000, b=001, ..., f=101). Aceast metod necesit
300 de bii pentru codificarea celor 100 de caractere din fiier.
O codificare cu lungime variabil, care atribuie coduri scurte caracterelor frecvente
i coduri lungi caracterelor cu frecven redus, poate codifica fiierul prin 224 de
bii (45x1+13x3+12x3+16x3+9x4+5x4), economisind 25% din spaiu.
O codificare optim pentru un fiier este reprezentat printr-un arbore binar
complet.
201
n exemplul anterior
a=0
b = 101
c = 100
d = 111
e = 1101
f = 1100
e:9
c:12
b:13
d:16
a:45
c:12
b:13
d:16
0
f:5
0
c:12
e:9
a:45
25
25
b:13
a:45
30
0
1
b:13
e:9
55
1
d:16
14
0
f:5
25
0
c:12
d:16
100
55
0
14
0
f:5
a:45
a:45
30
1
b:13
0
c:12
a:45
1
e:9
0
f:5
14
d:16
14
1
e:9
25
0
c:12
30
0
1
b:13
1
d:16
14
0
f:5
1
e:9
204
205
2.
3.
4.
5.
6.
F (n) = 1, n = 1
F (n 1) + F (n 2), n > 1
F(1)
F(3)
F(2)
F(1)
F(2)
F(0) F(1)
F(1)
F(0)
F(0)
n cazul implementrii recursive, termenii sunt determinai de mai multe ori: F(2)
de trei ori i F(3) de dou ori, pentru calculul F(5). Astfel, varianta recursiv are
complexitate exponenial: O(2n).
Varianta iterativ memoreaz tot timpul rezultatele, deci are la baz programarea
dinamic. Calculnd o singur dat termenii, complexitatea este liniar: O(n).
209
Exemplu:
10
76 1
45 2
68 52 90 0
15
-1 11 12 -1
11
12
c1 n + c 2
n( n 1)
+ c3 n = an 2 + bn + c = O (n 2 )
2
213
81
10
14
35
41
52
26
15
32
90
11
87
56
23
54
65
89
32
71
31
214
Pentru n=2 i 3 nu exist soluii, pentru n=4 sunt dou soluii, etc.
216
ACCEPT (k, i)
for j 1 to k-1 do
if S[j]=i then
return FALSE
if ABS(j-k)=ABS(S[j]-i) then
return FALSE
return TRUE
217
2.
3.
vi = F (ci ), i = 1, nc
Selecia
S = vi
i =1
pj =
i =1
vi
,
S
j = 1, nc ,
p nc = 1
Funcia MAX reprezint algoritmul genetic n sine, care determin maximul funciei
F(x), cu x[li, ls]. Funcia folosete o populaie C de nc cromozomi. Cutarea se
termin dup ng=50 de generaii.
221
MUTATIE (C, p)
cp C[p]
for j 1 to 16 do
if pmutatie>RANDOM(0, 1) then
if GETBIT(cp, j)=1 then
RESETBIT(cp, j)
else SETBIT(cp, j)
if F(X(cp))>F(X(C[p])) then
C[p] cp
223
224
MODIFICARE (C)
for i 1 to nc do
MUTATIE (C, i)
225
2.
3.
227
VHID
VOUT
o1
xN
oP
y = wi xi
i =1
1
f ( y) =
1 + ey
1
y
y
-1
1 ey
f ( y) =
1 + ey
1 e y
f ( y) =
1+ ey
i intrri codificate cu -1 i 1, const n urmtorii pai:
1. Se creeaz o reea neuronal cu N intrri, M uniti ascunse i P
uniti de ieire.
2. Se iniializeaz ponderile
wij1 ; i = 1, N ; j = 1, M
w 2jk ; j = 1, M ; k = 1, P
cu valori aleatoare mici [Mit97] din intervalul (-0.05, 0.05).
231
1 P
EW =
t k ok2
2 k =1
3. Ct timp
>T
repet
j = 1, ..., M
i =1
x 2j = o1j = f ( net 1j ),
M
net = w 2jk x 2j ,
2
k
j = 1, ..., M
k = 1, ..., P
j =1
o k2 = f ( net k2 ),
k = 1, ..., P
k2 = t k ok2 f (net k2 ) =
)(
1
t k ok2 1 ok2 ok2
2
232
1j
k =1
k2
w 2jk
(net 1j )
P
1
1
1
= 1 o j o j k2 w 2jk
2
k =1
w 2jk = w 2jk + k2 x 2j ,
wij1 = wij1 + 1j xi1 ,
unde
j = 1, M ,
i = 1, N ,
k = 1, P
j = 1, M
233
Aplicaii propuse
1.
1
f ( y) =
1 + e y
2.
3.
Nota final
Nota laborator (NL) = 0,2*T1 + 0,2*T2 + 0,1*A + 0,5*C
Nota final = 0,5*NL + 0,5*E
Bibliografie
Algoritmi
[Knu00] Knuth D., Arta programrii calculatoarelor, Vol. 1 Algoritmi fundamentali, Teora, 2000.
[Knu02] Knuth D., Arta programrii calculatoarelor, Vol. 3 Sortare i cutare, Teora, 2002.
[Cor00] Cormen T., Leiserson C., Rivest R., Introducere n algoritmi, Agora, 2000.
[Giu04] Giumale C., Introducere n analiza algoritmilor, Polirom, 2004.
[Log07] Logoftu D., Algoritmi fundamentali n Java, Polirom, 2007.
[Wai01] Waite M., Lafore R., Structuri de date i algoritmi n Java, Teora, 2001.
[Cri98] Cristea V., Athanasiu I., Kalisz E., Iorga V., Tehnici de programare, Teora 1998.
[Mit97] Mitchell T., Machine Learning, McGraw-Hill, 1997.
Programare n Java
[Rob00] Roberts S., Heller P., Ernest M., Complete Java 2 Certification, Second Edition, SYBEX, USA, 2000.
[Cha01] Chan M., Griffith S., Iasi A., Java 1001 secrete pentru programatori, Teora, 2000.
[Tan07] Tanas ., Andrei ., Olaru C., Java de la 0 la expert, Polirom, 2007.
[Hun01] Hunter J., Crawford W., Java Servlet Programming, Second Edition, OReilly, USA, 2001.
[Gea01] Geary D., Advanced JavaServer Pages, Prentice Hall, USA, 2001.
[Gor98] Gordon R., Java Native Interface, Prentice Hall, USA, 1998.
236
Webliografie
[Web01]
[Web02]
[Web03]
[Web04]
[Web05]
http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html
http://www.javapassion.com/javaintro/
http://thor.info.uaic.ro/~acf/java/curs/cursuri.html
http://labs.cs.utt.ro/labs/sdaa/html/LabSDA.html
http://www.personal.kent.edu/~rmuhamma/Algorithms/algorithm.html
237