0

I am trying to make couples out of an array of names (naam). These couples need to be unique every time I run it. The case is a teacher trying to make couples for amountWeeks weeks, the couples have to be unique from the other weeks and can't have Bob - Alice and Alice - Bob. If you haven't noticed, yes this is an assignment. I know your policy towards this, but I've been stuck on this for so long that even a push in the right direction would help a ton.

I have been doing it like this:

for (int n = 1; n < amountWeeks + 1; n++) {
    Object[] x = {"WEEK", "<html><b>" + n + "</b></html>"};
    model.addRow(x);
    pos1 = 1;
    pos2 = naam.size() - n;
    for (int i = 0; i < naam.size() / 2; i++) {
        Object[] row = {naam.get(pos1), naam.get(pos2)};
        pos1++;
        pos2 = pos2 - n;
        if (pos2 == pos1) {
            pos2 = pos2 - 1;
        }
        if (pos2 < (naam.size() - 1) / 2) {
            pos2 = pos2 + (naam.size() - 1) / 2;
        }
        model.addRow(row);
    }
}

But this produces doubles and as far as I know isn't the best way of doing this?

Community
  • 1
  • 1
Martijn Nosyncerror
  • 172
  • 1
  • 3
  • 16
  • You're getting doubles as in you're getting `Bob - Alice` and `Alice -Bob`? To avoid doubles, create another array which is a copy of the original array of names. Then, as you make a couple, remove the couple names from the array so they can't be selected again. – dsrees Jan 14 '15 at 13:39
  • A better solution would be to use a model class, that holds a couple and implements the `Comparable` interface (you can check there if the compared couple is the same constellation of peoples)). Then use a `List` and check if a couple is already in the list. Create a new couple if that is the case. You could also use `Set`, but you have to check the returned value of `Set#add(E)`if the couple was added or not. If not, then there is already a similar couple in there and you need to create another one. – Tom Jan 14 '15 at 13:41
  • Hey guys thanks for answering. I already have a somewhat checking function for doubles, I was wondering if there is a way of having less doubles by have a better coupling system. If there really isn't another way I will try building a 'filter' as you are suggesting. – Martijn Nosyncerror Jan 14 '15 at 13:49

1 Answers1

1

If I understand the question correctly I would restate it as "how do I obtain from a given list a new list of random and unique pairs". Let me know if that's incorrect.

If so then it can be split into a few separate problems.

Firstly how do you obtain a random pair from a list. The simplest way is to shuffle the list and take the first two items:

Collections.shuffle(list);
List<Object> pair = Arrays.asList(list.get(0), list.get(1));

Secondly, how do you check if the pair is already in the result list. This is easy if you always sort the list before you add it:

Collections.sort(pair);
if (!resultList.contains(pair)) {
    resultList.add(pair);
}

The reason this works is that contains calls equals on the items which, because they are lists, will return true if they are the same size and each item is equal.

Finally, how do you ensure you end up with the right number of items in the list. You really just need to check the size in a while loop.

resultList = new ArrayList<>();
while (resultList.size() < n) {
    ....
}

I'll leave it to you to put it all together. I will note that you have a danger that the source list is not long enough to generate enough pairs. You could fairly trivially check that as an entry condition to the method but I'll leave you to figure that one out as well.

If no randomness is required then you can just work through the list systematically:

for (int first = 0; resultList.size() < n && first < list.size(); first++) {
    for (int second = first + 1; resultList.size() < n && second < list.size(); second++) {
        resultList.add(Arrays.asList(list.get(first), list.get(second)));
    }
}

This guarantees that the pairs are unique because the second index is always larger than the first.

sprinter
  • 27,148
  • 6
  • 47
  • 78
  • Hey thanks, but would the ``Collections.shuffle(list)`` just shuffle the list? In that case I could just do ``list.get(random)``and keep checking if it's been done before? I was wondering if there's a more structured way of doing this, instead of using anything random – Martijn Nosyncerror Jan 14 '15 at 14:15
  • Yes Collection.shuffle just shuffles the list. The advantage over list.get(random) is that you don't need to check if the two items in the pair are the same item. – sprinter Jan 14 '15 at 14:18
  • If by 'more structured' you mean 'less random' then yes you can certainly do that. I'll add some tips to my answer. – sprinter Jan 14 '15 at 14:19