1

Where should I look if I want to write a piece of code which looks for Array1 in Array2, regardless of the order (keeping the duplicates in mind)? e.g.

Array1: { 2,5,6,6,3 }
Array2: { 1,2,3,4,5,6,6 }
will return true


Array1: { 2,5,6,6,3 }
Array2: { 1,2,3,4,5,6 }
will return false

I sort of want to solve it myslef, I just need to be pointed in some direction.

Thanks in advance.

HajdaCZ
  • 73
  • 13
  • 2
    I'm not sure I understand your logic. Your first example certainly *looks* like it is contained, and the other *could* be if you ignore duplicates. – BradleyDotNET Dec 09 '14 at 17:48
  • What exactly do you mean by "keep the duplicities in mind"? – Jon Skeet Dec 09 '14 at 17:48
  • Fixed wording. Means that if Array1 contains an element more times, it'll have to find it at least that number of times to return true. EDIT: Also fixed the swapped true/false. My fault. – HajdaCZ Dec 09 '14 at 17:51
  • Duplicate/related: http://stackoverflow.com/questions/332973/check-whether-an-array-is-a-subset-of-another – BradleyDotNET Dec 09 '14 at 17:53
  • 1
    As a hint: Use a `Dictionary` and store the quantity (used as value) of each number (used a key) of Array2. – Olivier Jacot-Descombes Dec 09 '14 at 17:56
  • @BradleyDotNET I don't think that question deals with duplicates in the way the OP wants. – juharr Dec 09 '14 at 17:56
  • That might be the problem. English is my second language and I sort of didn't know the meaning of "subset" in this context. Thank you. Working for arrays as well, or do I have to convert? – HajdaCZ Dec 09 '14 at 17:56
  • @BradleyDotNET: This is not duplicate, since this solution does not take into account the number of occurrences of the numbers. – Olivier Jacot-Descombes Dec 09 '14 at 17:58
  • Arrays are `IEnumerable` so the LINQ solution will work out of the box. You will have to deal with the duplicate problem though. – BradleyDotNET Dec 09 '14 at 17:58
  • @OlivierJacot-Descombes Agreed, not an actual duplicate (didn't VTC). Still related though, and may give the "hint" he is looking for. – BradleyDotNET Dec 09 '14 at 17:58

1 Answers1

0

Well, since you only want hints rather than code, one method would be:

  1. Copy array2 into a List<int>.

  2. Sort it.

  3. Allocate a bit array called used equal to the size of the list. These will be flags indicating whether a specific item in the sorted list has been used for a match.

  4. For each item item in array1:

    4.1 Binary search the sorted list for item.

    4.2. If not found, return false -- array2 does not contain array1.

    4.3. If found, and there are duplicates, the binary search algorithm will randomly return the index of one of the duplicates. Scan backward in the portion of the list that matches item until you find one for which used[i] is false. If you find one, set used[i] to true, and continue the outer loop. If you don't find one, scan forward from the initial binary search index, trying to find an unused match. Similarly set used[index] to true if one is found, and continue looping through array1.

    4.4 If no unused match is found, return false -- array2 does not contain array1.

  5. Having found an unused match for each item in array1, return true: array1 is contained inside array2.

An advantage of this algorithm is that, to check multiple arrays for being contained in a given array, you don't need to re-sort the array every time, you only need to re-allocate the BitArray.

dbc
  • 104,963
  • 20
  • 228
  • 340