简体   繁体   中英

Counting non-repeating matching pairs in a Java array

I'm new to java, and through my searches have found numerous posts on ALMOST what I'm looking for but not quite. I'm trying to use elementary java techniques to count the number of UNIQUE times a number has a match. For instance the array {2,3,2,3,2} would have two unique matching pair cases (2,2) and (3,3) So far (see below code) all I can seem to come up with is a count of how many TOTAL mached pairs there are. in the example case the result would be four cases (2,2), (2,2), (3,3), (2,2). To be clear this is 1st semester problem type stuff, so I can't use Map or more advanced techniques. Simple loops with counts and iterations. Thanks

int count = 0;
    for( int i=0;i<=hand.length-2 ;i++)
    {
        for( int j=i+1;j<=hand.length-1;j++)
        {
            if (hand[j] == hand[i])
            {

                count = count + 1;
            }
        }
    }
    System.out.println(count);

Java 8

If you can use Java 8, it's pretty simple to use to the streams API to group up elements and check how many of them belong to at least one pair:

    Integer[] data = { 2, 3, 2, 3, 2 };

    // create a map of each value to a list containing all instances of that value in the array
    Map<Integer, List<Integer>> map = Arrays.stream(data).collect(Collectors.groupingBy(i -> i));

    // count how many of those lists have more than one element, i.e. pairs
    long uniquePairs = map.values().stream().filter(l -> l.size() > 1).count();

    System.out.println(uniquePairs);

Java 7

If you're stuck using Java 7, it's a little more complicated, but you can create a map that contains elements as keys and a count of how many times they appear in the array as values. Then you can traverse the values of the map looking for elements that occur at least twice (ie belong to at least one pair):

    Integer[] data = { 2, 3, 2, 3, 2 };

    // create a map of each element to a count of the times that element appears in the array
    Map<Integer, Integer> map = new HashMap<>();
    for (int i : data) {
        Integer oldCount = map.get(i);
        int newCount = oldCount == null ? 1 : oldCount + 1;
        map.put(i, newCount);
    }

    // count the number of elements that appear more than once, i.e. pairs
    int uniquePairs = 0;
    for (int i : map.values()) {
        if (i > 1) uniquePairs++;
    }

    System.out.println(uniquePairs);

@azurefrog gives a good answer already. Here is an implementation that counts pairs that have more than 3 entries for a given number:

List<Integer> numbers = Arrays.asList(2, 3, 2, 3, 2, 2, 9);
Map<Integer, Long> map = numbers.stream()
        .collect(Collectors.groupingBy(num -> num, Collectors.counting()))
        .entrySet()
        .stream()
        .collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue() / 2));

// output
map.forEach((num, count) -> System.out.println(String.format("%d has %d unique pairs", num, count)));
Long total = map.values().stream().reduce((acc, c) -> c + acc).get();
System.out.print(String.format("A total of %d pairs", total));

Taking into account your other constraints listed in the comments: no modifing original data, simple loops, only 'simple' data structures;

One method would be to track whether you have seen an element before (I do this with a boolean array):

int[] hand = {2,3,2,3,2,9,5,5,5,5,5,5,5};
boolean[] hasPair = new boolean[10];
for(int i = 0; i <= hand.length - 2 ; i++) {
    for(int j= i + 1; j <= hand.length - 1; j++) {
        if (hand[j] == hand[i]) {
            hasPair[hand[j]] = true;
        }
    }
}
int count = 0;
for (boolean b : hasPair) {
    if (b) {
        count += 1;
    }
}
System.out.print(count);

This counts unique pairs or 'duplicates', assumes that input array is of int in {1, ..., 9}

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