简体   繁体   中英

How to get intersection of two Arrays

I have two integer arrays

    int A[] = {2, 4, 3, 5, 6, 7};
    int B[] = {9, 2, 7, 6};

And i have to get intersection of these array.

ie output will be - 2,6,7

I am thinking to sove it by saving array A in a data strcture and then i want to compare all the element till size A or B and then i will get intersection.

Now i have a problem i need to first store the element of Array A in a container.

shall i follow like -

int size = sizeof(A)/sizeof(int);

To get the size but by doing this i will get size after that i want to access all the elemts too and store in a container.

Here i the code which i am using to find Intersection ->

#include"iostream"

using namespace std;


int A[] = {2, 4, 3, 5, 6, 7};
int B[] = {9, 2, 7, 6};

int main()
{
    int sizeA = sizeof(A)/sizeof(int);

    int sizeB = sizeof(B)/sizeof(int);

    int big =  (sizeA > sizeB) ? sizeA : sizeB;

    int small =  (sizeA > sizeB) ? sizeB : sizeA;

    for (int i = 0; i <big ;++i)
    {
        for (int j = 0; j <small ; ++j)
        {
            if(A[i] == B[j])
            {
                cout<<"Element is -->"<<A[i]<<endl;
            }
        }
    }

    return 0;
}

Just use a hash table :

#include <unordered_set>  // needs C++11 or TR1 
// ...
unordered_set<int> setOfA(A, A + sizeA);

Then you can just check for every element in B , whether it's also in A :

for (int i = 0; i < sizeB; ++i) {
    if (setOfA.find(B[i]) != setOfA.end()) {
        cout << B[i] << endl;
    }
}

Runtime is expected O(sizeA + sizeB) .

saving array A in a data strcture

Arrays are data structures; there's no need to save A into one.

i want to compare all the element till size A or B and then i will get intersection

This is extremely vague but isn't likely to yield the intersection; notice that you must examine every element in both A and B but "till size A or B" will ignore elements.

What approach i should follow to get size of an unkown size array and store it in a container??

It isn't possible to deal with arrays of unknown size in C unless they have some end-of-array sentinel that allows counting the number of elements (as is the case with NUL-terminated character arrays, commonly referred to in C as "strings"). However, the sizes of your arrays are known because their compile-time sizes are known. You can calculate the number of elements in such arrays with a macro:

#define ARRAY_ELEMENT_COUNT(a) (sizeof(a)/sizeof *(a))

...

int *ptr = new sizeof(A);

[Your question was originally tagged [C], and my comments below refer to that]

This isn't valid C -- new is a C++ keyword.

If you wanted to make copies of your arrays, you could simply do it with, eg,

int Acopy[ARRAY_ELEMENT_COUNT(A)];
memcpy(Acopy, A, sizeof A);

or, if for some reason you want to put the copy on the heap,

int* pa = malloc(sizeof A);
if (!pa) /* handle out-of-memory */
memcpy(pa, A, sizeof A);
/* After you're done using pa: */
free(pa);

[In C++ you would used new and delete ]

However, there's no need to make copies of your arrays in order to find the intersection, unless you need to sort them (see below) but also need to preserve the original order.

There are a few ways to find the intersection of two arrays. If the values fall within the range of 0-63, you can use two unsigned long s and set the bits corresponding to the values in each array, then use & (bitwise "and") to find the intersection. If the values aren't in that range but the difference between the largest and smallest is < 64, you can use the same method but subtract the smallest value from each value to get the bit number. If the range is not that small but the number of distinct values is <= 64, you can maintain a lookup table (array, binary tree, hash table, etc.) that maps the values to bit numbers and a 64-element array that maps bit numbers back to values.

If your arrays may contain more than 64 distinct values, there are two effective approaches:

1) Sort each array and then compare them element by element to find the common values -- this algorithm resembles a merge sort.

2) Insert the elements of one array into a fast lookup table (hash table, balanced binary tree, etc.), and then look up each element of the other array in the lookup table.

Sort both arrays (eg, qsort() ) and then walk through both arrays one element at a time.

Where there is a match, add it to a third array, which is sized to match the larger of the two input arrays (your result array can be no larger than the largest of the two arrays). Use a negative or other "dummy" value as your terminator.

When walking through input arrays, where one value in the first array is larger than the other, move the index of the second array, and vice versa.

When you're done walking through both arrays, your third array has your answer, up to the terminator value.

You can sort the two arrays

sort(A, A+sizeA);
sort(B, B+sizeB);

and use a merge-like algorithm to find their intersection:

#include <vector>

...

std::vector<int> intersection;
int idA=0, idB=0;

while(idA < sizeA && idB < sizeB) {
    if (A[idA] < B[idB]) idA ++;
    else if (B[idB] < A[idA]) idB ++;
    else { // => A[idA] = B[idB], we have a common element
        intersection.push_back(A[idA]);
        idA ++;
        idB ++;
    }
}

The time complexity of this part of the code is linear. However, due to the sorting of the arrays, the overall complexity becomes O(n * log n), where n = max(sizeA, sizeB).

The additional memory required for this algorithm is optimal (equal to the size of the intersection).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM