J'ai un problème pour trouver des éléments communs dans deux tableaux de taille différente.
Take, Tableau A1
de taille n
et Tableau A2
de taille m
et m != n
Jusqu'à présent, j'ai essayé de parcourir les listes une par une et de copier les éléments dans une autre liste. Si l'élément contient déjà le marquer, mais je sais que ce n'est pas une bonne solution.
Triez les tableaux. Puis parcourez-les avec deux pointeurs, en faisant toujours avancer celui qui pointe vers la valeur la plus petite. Quand ils pointent vers des valeurs égales, vous avez une valeur commune. Ce sera O (n + m) où n et m sont les tailles des deux listes. C'est comme une fusion dans merge sort , mais vous ne produisez une sortie que lorsque les valeurs pointées sont égales.
def common_elements(a, b):
a.sort()
b.sort()
i, j = 0, 0
common = []
while i < len(a) and j < len(b):
if a[i] == b[j]:
common.append(a[i])
i += 1
j += 1
Elif a[i] < b[j]:
i += 1
else:
j += 1
return common
print 'Common values:', ', '.join(map(str, common_elements([1, 2, 4, 8], [1, 4, 9])))
les sorties
Common values: 1, 4
Si les éléments ne sont pas comparables, jetez les éléments d'une liste dans une table de hachage et comparez les éléments de la deuxième liste avec la table de hachage.
Si vous voulez le rendre efficace, je convertirais le plus petit tableau en un hashset, puis itérerais le plus grand et vérifierais si l'élément en cours était contenu dans le hashset. La fonction de hachage est efficace par rapport au tri des tableaux. Le tri des tableaux coûte cher.
Voici mon exemple de code
import Java.util.*;
public class CountTest {
public static void main(String... args) {
Integer[] array1 = {9, 4, 6, 2, 10, 10};
Integer[] array2 = {14, 3, 6, 9, 10, 15, 17, 9};
Set hashSet = new HashSet(Arrays.asList(array1));
Set commonElements = new HashSet();
for (int i = 0; i < array2.length; i++) {
if (hashSet.contains(array2[i])) {
commonElements.add(array2[i]);
}
}
System.out.println("Common elements " + commonElements);
}
}
Sortie:
Éléments communs [6, 9, 10]
En APL:
∪A1∩A2
exemple:
A1←9, 4, 6, 2, 10, 10
A1
9 4 6 2 10 10
A2←14, 3, 6, 9, 10, 15, 17, 9
A2
14 3 6 9 10 15 17 9
A1∩A2
9 6 10 10
∪A1∩A2
9 6 10
La complexité de ce que je donne est O(N*M + N)
.
Notez également qu'il s'agit de Pseudocode C et qu'il fournit des valeurs distinctes.
par exemple .[1,1,1,2,2,4]
et [1,1,1,2,2,2,5]
retournera [1,2]
La complexité est de N*M
cause des boucles for
+ N
cause de la vérification si elle existe déjà dans le ArrayCommon[]
(qui est n
taille dans le cas où Array2[]
contient des données qui dupliquent une partie du Array1[]
en supposant que N est la taille du plus petit tableau (N <M).
int Array1[m] = { Whatever };
int Array2[n] = { Whatever };
int ArrayCommon[n] = { };
void AddToCommon(int data)
{
//How many commons we got so far?
static int pos = 0;
bool found = false;
for(int i = 0 ; i <= pos ; i++)
{
//Already found it?
if(ArrayCommon[i] == data)
{
found = true;
}
}
if(!found)
{
//Add it
ArrayCommon[pos] = data;
pos++;
}
}
for(int i = 0 ; i < m ; i++)
{
for(int j = 0 ; j < n ; j++)
{
//Found a Common Element!
if(Array1[i] == Array2[j])
AddToCommon(Array1[i]);
}
}
En Python, vous écririez set(A1).intersection(A2)
. C'est l'optimum O (n + m).
Il y a cependant une ambiguïté dans votre question. Quel est le résultat de A1 = [0, 0], A2 = [0, 0, 0]? Il y a des interprétations raisonnables de votre question qui donnent 1, 2, 3 ou 6 résultats dans le tableau final.
Je résous le problème en utilisant Set intersection. C'est très élégant. Même si je n’ai pas analysé la complexité temporelle, c’est probablement dans une fourchette raisonnable.
public Set FindCommonElements(Integer[] first, Integer[] second)
{
Set<Integer> set1=new HashSet<Integer>(Arrays.asList(first));
Set<Integer> set2=new HashSet<Integer>(Arrays.asList(second));
// finds intersecting elements in two sets
set1.retainAll(set2);
return set1;
}
On dirait des boucles imbriquées:
commons = empty
for each element a1 in A1
for each element a2 in A2
if a1 == a2
commons.add(a1)
Schould n'a pas d'importance du tout si les tableaux ont la même taille.
Selon le langage et le cadre utilisés, les opérations sur les ensembles peuvent s'avérer utiles.
Essayez heapifying les deux tableaux, suivis d’une fusion pour trouver l’intersection.
Exemple Java:
public static <E extends Comparable<E>>List<E> intersection(Collection<E> c1,
Collection<E> c2) {
List<E> result = new ArrayList<E>();
PriorityQueue<E> q1 = new PriorityQueue<E>(c1),
q2 = new PriorityQueue<E>(c2);
while (! (q1.isEmpty() || q2.isEmpty())) {
E e1 = q1.peek(), e2 = q2.peek();
int c = e1.compareTo(e2);
if (c == 0) result.add(e1);
if (c <= 0) q1.remove();
if (c >= 0) q2.remove();
}
return result;
}
Voir cette question pour plus d'exemples de fusion.