Sunteți pe pagina 1din 27

1

Prezentare 11:
Exemple

PROGRAMARE ORIENTATA
OBIECT
2020
Permutari

 Dandu-se doua siruri de caractere, sa se scrie o metoda care


decide daca unul este permutarea celuilalt
 Intrebare: este permutarea case-sensitive?

 Observatie: siruri de lungimi diferite nu pot fi permutari

22.11.2020 POO 2
Permutari
Solutia 1: sortam sirurile si le comparam

String sort(String s) {
char[] continut = s.toCharArray();
java.util.Arrays.sort(continut);
return new String(continut);
}

boolean permutare(String s, String t) {


if (s.length() != t.length())
return false;
return sort(s).equals(sort(t));
}

22.11.2020 POO 3
Permutari
Solutia 2: permutarile au acelasi numar de aparitii ale caracterelor
boolean permutare(String s, String t) {
if (s.length() != t.length()) return false;
int [] litere = new int[128];
for (int i = 0; i < s.length(); i++)
litere[s.charAt(i)]++;
for (int i = 0; i < t.length(); i++) {
litere[t.charAt(i)]--;
if (litere[t.charAt(i)] < 0)
return false;
}
return true; //litere nu contine valori negative, deci nici pozitive
}
22.11.2020 POO 4
Duplicate

 Sa se scrie o metoda care elimina duplicatele dintr-o lista


inlantuita neordonata.
 Intrebare: putem utiliza memorie suplimentara?

22.11.2020 POO 5
Duplicate
 Solutia 1: memorie suplimentara – hash table
void elimDup(LinkedListNode n) {
HashSet<Integer> set = new HashSet<>();
LinkedListNode prev = null;
while (n != null) {
if (set.contains(n.data))
prev.next = n.next; Complexitate: O(n)
else {
set.add(n.data);
prev = n;
}
n = n.next;
}
}
22.11.2020 POO 6
Duplicate
 Solutia 2: fara memorie suplimentara
void elimDup(LinkedListNode cap) {
LinkedListNode curent = cap;
while (curent != null) {
// elimina urmatoarele noduri cu aceeasi valoare
LinkedListNode urm = curent;
while (urm.next != null) { Complexitate: O(n^2)
if (urm.next.data == curent.data)
urm.next = urm.next.next;
else
urm = urm.next;
}
curent = curent.next;
}
22.11.2020 } POO 7
Eliminarea unui nod din interiorul unei liste

 Sa se implementeze un algoritm care sterge un nod din interiorul unei


liste inlantuite (orice nod in afara de primul si ultimul), avand doar o
referinta la acel nod
 Exemplu:

Input: nodul c din lista a->b->c->d->e->f


Rezultat: nu se intoarce nimic, dar lista devine: a->b->d->e->f

22.11.2020 POO 8
Eliminarea unui nod din interiorul unei liste

 Solutie: se copiaza informatia din urmatorul nod in nodul curent


si apoi se sterge nodul urmator
 Observatie: problema nu poate fi rezolvata daca nodul care
trebuie eliminat este ultimul din lista

boolen elimNod(LinkedListNode n) {
if (n == null || n.next == null)
return false;
LinkedListNode urm = n.next;
n.data = urm.data;
n.next = next.next;
return true;
}
22.11.2020 POO 9
Vector circular

 Sa se implementeze o clasa VectorCircular care defineste o structura de


date de tip vector(array) care poate fi rotit eficient. Clasa trebuie sa fie
parametrizata si sa permita iterare utilizand constructia standard:
for (Obj o: vectorCircular)

22.11.2020 POO 10
Vector circular

 Solutie: se utilizeaza o variabila cap care indica inceputul


“conceptual” al vectorului circular; deplaseazaDreapta va
incrementa variabila
public class VectorCircular<T> {
private T[] elem;
private int cap = 0;

public VectorCircular(int dim) {


elem = (T[]) new Object[dim];
}

22.11.2020 POO 11
Vector circular
private int convert(int ind) {
if (ind < 0)
ind += elem.length; // -8 % 3 = -2
return (cap + ind) % elem.length;
}

public void roteste(int deplDr) {


cap = convert(deplDr);
}

public T get(int i) {
if (i < 0 || i >= elem.length)
throw new java.lang.IndexOutOfBoundsException(“…”);
return elem[convert(i)];
}
22.11.2020 POO 12
Vector circular

public void set(int i, T el) {


elem[convert(i)] = el;
}
} // end VectorCircular

22.11.2020 POO 13
Vector circular
 Implementarea interfetei Iterator a.i. sa putem scrie:
VectorCircular<String> arr = …
for (String s: arr) { …}
 Clasa VectorCircular<T> trebuie sa implementeze interfata
Iterable<T>
 Implica adaugarea metodei iterator()
 Crearea unui VectorCircularIterator<T> care implementeaza
Iterator<T> si definirea metodelor hasNext(), next() si
remove()

22.11.2020 POO 14
Vector circular
public class VectorCircular<T> implements Iterable<T> {

public Iterator<T> iterator() {
return new VectorCircularIterator();
}

private class VectorCircularIterator implements Iterator<T> {


private int curent = -1;

public VectorCircularIterator() {}
@override
public Boolean hasNext() {
return curent < elem.length – 1;
}
22.11.2020 POO 15
Vector circular
@override
public T next() {
current++;
return (T) elem[convert(curent)];
}

@override
public void remove() {
throw new UnsupportedOperationException(“Remove nu este
implementata”);
}
}
}

22.11.2020 POO 16
Gruparea anagramelor
 Sa se scrie o metoda care sorteaza un vector de cuvinte
a.i. toate anagramele sa fie una langa alta
 Anagrame sunt cuvintele care au aceleasi litere in alta
ordine

22.11.2020 POO 17
Gruparea anagramelor
 Solutia 1: sortam sirurile modificand comparatorul
class CompAnagram implements Comparator<String> {
private String sortChars(String s) {
char[] continut = s.toCharArray();
Arrays.sort(continut);
return new String(continut);
} Complexitate: O(n log(n))
public int compare(String s1, String s2) {
return sortChars(s1).compareTo(sortChars(s2));
}
}

Arrays.sort(arr, new CompAnagram()); //sortam vectorul folosind
comparatorul
23.11.2020 POO 18
Gruparea anagramelor
 Solutia 2: utilizam o tabela hash care mapeaza cuvantul
sortat la lista anagramelor sale

void sort(String[] arr) {


HashMapList<String, String> mapList = new HashMapList<>();
// grupeaza cuvintele dupa anagrame
for (String s: arr) {
String key = sortChars(s);
mapList.put(key, s);
}

22.11.2020 POO 19
Gruparea anagramelor

// conversia tabelei hash la array


int ind = 0;
for (String key: mapList.keyset()) {
ArrayList<String> list = mapList.get(key);
for (String t: list) {
array[ind] = t;
ind++;
}
}
}

22.11.2020 POO 20
Gruparea anagramelor

String sortChars(string s) {
char[] continut = s.toCharArray();
Arrays.sort(continut);
return new String(continut);
}

/** HashMapList<String, String> este un HashMap care mapeaza string


la ArrayList<String>
*/

22.11.2020 POO 21
Varfuri si vai
 Intr-un vector de numere intregi, un varf este un element
care este mai mare sau egal in raport cu numerele
adiacente iar o vale este un element care este mai mic sau
egal in raport cu vecinii sai. De exemplu pentru vectorul
[5, 8, 6, 2, 3, 4, 6], {8, 6} sunt varfuri, iar {5, 2} sunt vai.
Dandu-se un vector de numere intregi, sa se sorteze
vectorul intr-o alternanta de varfuri si vai.
 Exemplu:
Input: [5, 3, 1, 2, 3]
Output: [5, 1, 3, 2, 3]

23.11.2020 POO 22
Varfuri si vai
 Solutia 1:
1. Sortam vectorul in ordine ascendenta
2. Iteram in vector incepand cu indexul 1si sarind peste
2 elemente
3. Pentru fiecare element il interschimbam cu
precedentul. Cum fiecare 3 elemente apar in ordinea
mic <= mediu <= mare, interschimband elementele
vom pune elementul mediu ca varf
014789
• 0 e ok
• 1 trebuie schimbat; interschimbam 1 cu 0
104789
• 4 e ok
• Interschimbam 7 cu 4
107489
• Interschimbam 9 cu 8
107489
23.11.2020 POO 23
Varfuri si vai

void sortVV(int[] arr) {


Arrays.sort(arr);
for(int i = 1; i < arr.length; i+=2)
swap(arr, i-1, i);
}

void swap(int[] arr, int l, int r) {


int aux = arr[l];
arr[l] = arr[r];
arr[r] = aux;
}

23.11.2020 POO 24
Varfuri si vai
 Solutia 2: putem optimiza solutia precedenta, eliminand
sortarea. Sa consideram secventele:
0 1 2 -> 0 2 1
0 2 1 //varf
1 0 2 -> 1 2 0
1 2 0 //varf
2 1 0 ->1 2 0
2 0 1 -> 0 2 1
Vrem ca elementul din mijloc sa fie varf – interschimbam
elementul din mijloc cu cel mai mare dintre elementele
adiacente.
Poate o astfel de interschimbare sa “strice” ordonarea
facuta deja? Daca interschimbam mijlocul cu stanga,
stanga este deja o vale, deci vom pune un element si mai
mic ca vale.

23.11.2020 POO 25
Varfuri si vai

void sortNVV(int[] arr) {


for(int i = 1; i < arr.length; i+=2) {
int indMax = maxInd(arr, i-1, i, i + 1);
if (i != indMax) Complexitate: O(n)
swap(arr, i, indMax);
}
}

23.11.2020 POO 26
Varfuri si vai

int maxInd(int[] arr, int a, int b, int c) {


int lg = arr.length;
int aVal = a >= 0 && a < lg ? arr[a] : Integer.MIN_VALUE;
int bVal = b >= 0 && b < lg ? arr[b] : Integer.MIN_VALUE;
int cVal = c >= 0 && c < lg ? arr[c] : Integer.MIN_VALUE;
int max = Math.max(aVal, Math.max(bVal, cVal));
if (aVal == max) return a;
else if (bVal == max) return b;
else return c;
}

23.11.2020 POO 27

S-ar putea să vă placă și