web-dev-qa-db-fra.com

Recherche d'éléments communs dans deux tableaux de taille différente

J'ai un problème pour trouver des éléments communs dans deux tableaux de taille différente.

Take, Tableau A1 de taille net Tableau A2 de taille met 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.

15
Jijoy

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.

28
marcog

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]

13
Jacorb Effect

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 
1
StackPC

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]);
    }
}
0
Muggen

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.

0
user97370

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;

}
0
alan turing

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.

0
Eiko

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.

0
finnw