2

English is not my native language: sorry for my mistakes. Thank you in advance for your answers.

I'm learning C++ and I'm trying to check to what extent two sets with the same number of integers--in whatever order--are bijective.

Example :

int ArrayA [4] = { 0, 0, 3, 4 };
int ArrayB [4] = { 4, 0, 0, 3 };

ArrayA and ArrayB are bijective.

My implementation is naive.

int i, x=0;    
std::sort(std::begin(ArrayA), std::end(ArrayA));
std::sort(std::begin(ArrayB), std::end(ArrayB));
for (i=0; i<4; i++) if (ArrayA[i]!=ArrayB[i]) x++;

If x == 0, then the two sets are bijective. Easy.

My problem is the following: I would like to count the number of bijections between the sets, and not only the whole property of the relationship between ArrayA and ArrayB.

Example :

int ArrayA [4] = { 0, 0, 0, 1 }
int ArrayB [4] = { 3, 1, 3, 0 }

Are the sets bijective as a whole? No. But there are 2 bijections (0 and 0, 1 and 1).

With my code, the output would be 1 bijection. Indeed, if we sort the arrays, we get:

ArrayA = 0, 0, 0, 1; ArrayB = 0, 1, 3, 3.

A side-by-side comparaison shows only a bijection between 0 and 0.

Then, my question is: Do you know a method to map elements between two equally-sized sets and count the number of bijections, whatever the order of the integers?

Solved!

The answer given by Ivaylo Strandjev works:

  1. Sort the sets,
  2. Use the std::set_intersection function,
  3. Profit.

1 Answers1

2

You need to count the number of elements that are contained in both sets. This is called set intersection and it can be done with a standard function - set_intersection, part of the header algorithm. Keep in mind you still need to sort the two arrays first.

Ivaylo Strandjev
  • 69,226
  • 18
  • 123
  • 176
  • Fantastic! It seems to be the solution. –  Sep 03 '14 at 14:01
  • A lot more elegant than my suggestion. =] – Bart van Nierop Sep 03 '14 at 14:02
  • After some tests: it IS the solution. Thanks Ivaylo! –  Sep 03 '14 at 15:17
  • @GuillaumeLethuillier If you are convinced that this is the solution you should mark the answer as accepted. – nwp Sep 03 '14 at 15:25
  • @BartvanNierop: It may appear elegant, but this actually is a lot slower as it constructs the intersection whereas your solution (in comment) avoids that. The algorithm you provided is actually the canonical one, and probably used inside `set_intersection`. – MSalters Sep 04 '14 at 11:20
  • @MSalters I had assumed that `set_intersection` would indeed be slower, and using my algorithm internally. =] – Bart van Nierop Sep 04 '14 at 11:36
  • @MSalters To add to my previous comment, I'd go with Knuth and use `set_intersection` until it proved to be too slow in practice. – Bart van Nierop Sep 04 '14 at 11:53
  • To join the discussion: @BartvanNierop your solution is faster and uses no extra memory, however it is harder to maintain or read as it is less obvious what it does. I think what you say is quite right - use set_intersection unless it proves too slow. – Ivaylo Strandjev Sep 04 '14 at 11:56