Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

[Algoritmi] Trovare l'elemento non comune a due liste

Linguaggi e sistemi

Moderatori: Foto UtentePaolino, Foto Utentefairyvilje

0
voti

[1] [Algoritmi] Trovare l'elemento non comune a due liste

Messaggioda Foto UtentePatras » 31 ago 2017, 9:47

Ciao a tutti! Ho la consegna di un esercizio ma non la soluzione quindi vi chiedo cortesemente di suggerirmi qualcosa se avete idee.
Consegna:
Date due liste A e B (non ordinate), ciascuna delle quali contiene elementi interi distinti,
si vuole determinare se esiste un elemento che compare in A ma non in B. Fornire un
algoritmo efficiente, scriverne lo pseudocodice e discuterne la complessità (ne esiste uno che
richiede tempo O(n) nel caso medio, dove n è il numero di elementi della lista più lunga).


Due soluzioni che mi vengono in mente (ma che non sembrano O(n) nel caso medio)
- Scandire una lista nel frattempo controllando la presenza dell'elemento nell'altra O(hm) \text{ dove } h=dim(A), m=dim(B)
- Creare un array dimensione n (quella dell'array più grande) e fare un MergeSort e scandirlo per verificare la presenza di duplicati prendendo ogni volta un elemento dall'altro facendo una ricerca binaria. Ma anche in questo caso abbiamo.. O((n+m)\log n) con m dimensione dell'altro array, che se è molto piccola è circa O(n \log n)

Con una funzione hash si può fare O(M) dove M è il massimo dei due array. Ma non mi sembra O(n) nel caso medio

Qualcuno ha qualche idea?
Avatar utente
Foto UtentePatras
51 1 7
Utente disattivato per decisione dell'amministrazione proprietaria del sito
 
Messaggi: 131
Iscritto il: 24 mag 2017, 15:27

0
voti

[2] Re: [Algoritmi] Trovare l'elemento non comune a due liste

Messaggioda Foto UtenteIlGuru » 31 ago 2017, 10:01

Verrebbe più semplice ordinando prima le due liste
\Gamma\nu\tilde{\omega}\theta\i\ \sigma\epsilon\alpha\upsilon\tau\acute{o}\nu
Avatar utente
Foto UtenteIlGuru
5.482 2 10 13
G.Master EY
G.Master EY
 
Messaggi: 1924
Iscritto il: 31 lug 2015, 23:32

0
voti

[3] Re: [Algoritmi] Trovare l'elemento non comune a due liste

Messaggioda Foto UtentePatras » 31 ago 2017, 10:31

Grazie per la risposta. Credo che l'ordinamento in se fatto per confronti , che sia prima o dopo aver fuso le liste, comunque non possa dar origine a prestazioni mediamente O(n)
Avatar utente
Foto UtentePatras
51 1 7
Utente disattivato per decisione dell'amministrazione proprietaria del sito
 
Messaggi: 131
Iscritto il: 24 mag 2017, 15:27

2
voti

[4] Re: [Algoritmi] Trovare l'elemento non comune a due liste

Messaggioda Foto UtenteGuidoB » 31 ago 2017, 23:39

Patras ha scritto:Date due liste A e B (non ordinate), ciascuna delle quali contiene elementi interi distinti,
si vuole determinare se esiste un elemento che compare in A ma non in B. Fornire un
algoritmo efficiente, scriverne lo pseudocodice e discuterne la complessità (ne esiste uno che
richiede tempo O(n) nel caso medio, dove n è il numero di elementi della lista più lunga).


Potresti inserire gli elementi della lista B in una tabella hash (O(n) se si generano poche collisioni) e poi controllare, per ogni elemento della lista A, se è già presente o no nella tabella (ancora O(n) se si generano poche collisioni).

Per generare poche collisioni, la tabella non deve essere troppo piena (non più del 75%, normalmente), e la funzione di hash deve essere "buona". Come farla "buona" è un po' complicato da spiegare qui...
Big fan of ƎlectroYou!       Ausili per disabili e anziani su ƎlectroYou
Caratteri utili: À È É Ì Ò Ó Ù α β γ δ ε η θ λ μ π ρ σ τ φ ω Ω º ª ² ³ √ ∛ ∜ ₀ ₁ ₂ ₃ ₄ ₅ ₆ ∃ ∄ ∆ ∈ ∉ ± ∓ ∾ ≃ ≈ ≠ ≤ ≥
Avatar utente
Foto UtenteGuidoB
17,8k 7 12 13
G.Master EY
G.Master EY
 
Messaggi: 2809
Iscritto il: 3 mar 2011, 16:48
Località: Madrid

0
voti

[5] Re: [Algoritmi] Trovare l'elemento non comune a due liste

Messaggioda Foto UtentePatras » 1 set 2017, 9:33

Posso ottimizzare la funzione hash traslando il range dopo aver trovato il minimo. Nel caso peggiore avrò comunque O(N-M) dove N è il massimo e M è il minimo. Cosa posso fare di meglio? Non conosco il "passo" tra due valori consecutivi per dividere. Posso trovare il massimo però. E così come dico io non credo che mediamente venga O(n), (N-M) può essere molto più grande di n. Però di sicuro è \Omega(n)
Avatar utente
Foto UtentePatras
51 1 7
Utente disattivato per decisione dell'amministrazione proprietaria del sito
 
Messaggi: 131
Iscritto il: 24 mag 2017, 15:27

1
voti

[6] Re: [Algoritmi] Trovare l'elemento non comune a due liste

Messaggioda Foto UtenteGuidoB » 1 set 2017, 20:17

Patras ha scritto:Posso ottimizzare la funzione hash traslando il range dopo aver trovato il minimo.

Non è necessario trovare il minimo (e il massimo). Si può fare in modo più efficiente.

Patras ha scritto:Nel caso peggiore avrò comunque O(N-M) dove N è il massimo e M è il minimo.

Nooo... La complessità di inserimento o ricerca di un elemento in una tabella hash non dipende dalle sue dimensioni ma dal grado di riempimento. Se non è troppo piena, è O(1), cioè costante e indipendente dal numero di elementi già presenti.
Se devi inserire o ricercare n elementi, la complessità sarà O(n).

Se ne parla un po' qui e in questo PDF.

Suggerimento di un possibile algoritmo:

1) trova quanti elementi contiene la lista B (complessità: O(n)). Chiamiamo questo numero nElementiB.
2) dimensioneTabellaHash = nElementiB * 1.5 // Il riempimento in questo esempio sarà 1/1.5 = 67%.
3) allochi memoria per la tabella hash, con le dimensioni appena calcolate, e la inizializzi con elementi "vuoti".
4) Inserisci nella tabella, uno per uno, gli elementi della lista B (complessità: O(n)). In caso di collisione, la risolvi in uno dei soliti modi: salti avanti o indietro di un certo numero di posizioni (magari variabile), oppure modifichi la funzione di hash a ogni collisione, oppure memorizzi gli elementi in liste concatenate...
5) Cerchi nella tabella, uno per uno, gli elementi della lista A (complessità: O(n)), e vedi se ce n'è qualcuno non presente.

La complessità totale è O(n).

La funzione di hash può essere semplicemente (per quest'uso la ritengo sufficientemente "buona"):

hash = valElemento % dimensioneTabellaHash (dove valElemento è il valore dell'intero da inserire, e % è il simbolo del modulo, ovvero il resto della divisione intera).


Se usi la standard library del C++, puoi dichiarare una unordered_map e hai già pronta tutta la classe che gestisce la tua tabella hash.

Ma mi sembra che a te basti lo pseudocodice...
Big fan of ƎlectroYou!       Ausili per disabili e anziani su ƎlectroYou
Caratteri utili: À È É Ì Ò Ó Ù α β γ δ ε η θ λ μ π ρ σ τ φ ω Ω º ª ² ³ √ ∛ ∜ ₀ ₁ ₂ ₃ ₄ ₅ ₆ ∃ ∄ ∆ ∈ ∉ ± ∓ ∾ ≃ ≈ ≠ ≤ ≥
Avatar utente
Foto UtenteGuidoB
17,8k 7 12 13
G.Master EY
G.Master EY
 
Messaggi: 2809
Iscritto il: 3 mar 2011, 16:48
Località: Madrid

0
voti

[7] Re: [Algoritmi] Trovare l'elemento non comune a due liste

Messaggioda Foto UtentePatras » 1 set 2017, 21:00

Grazie mille! Si sapevo che l'inserimento avvenisse in tempo costante però al passaggio finale che come lo considerato io avrei avuto anche celle vuote. Per quello mi toccava verificare più di n valori in generale.
GuidoB ha scritto:hash = valElemento % dimensioneTabellaHash (dove valElemento è il valore dell'intero da inserire, e % è il simbolo del modulo, ovvero il resto della divisione intera).

Così invece l'array può essere un po' più riempito ma sempre dagli n elementi e seguendo i passaggi indicati è perfetto. :ok:
Avatar utente
Foto UtentePatras
51 1 7
Utente disattivato per decisione dell'amministrazione proprietaria del sito
 
Messaggi: 131
Iscritto il: 24 mag 2017, 15:27


Torna a PC e informatica

Chi c’è in linea

Visitano il forum: Nessuno e 12 ospiti