Лучшее решение, чтобы получить дубликаты и считать в массиве?

У меня есть код ниже, который нацелен на поиск дублирующегося элемента в массиве и печать его с его количеством.

Я использовал следующий подход для решения проблемы.

  1. скопировать исходный массив во временный массив
  2. найти дубликаты в исходном массиве и удалить тот же
  3. скопировать неповторяющийся массив в другой временный массив
  4. сравните массив без дубликатов с исходным массивом и распечатайте дубликаты с их количеством.

Для расчета длины я использую собственную версию кода.

Это о / п 5 4 2 3

это правильно, но я хочу знать, сможем ли мы еще улучшить этот код.

Пожалуйста, предложите лучший подход, при условии, что не должно быть никаких встроенных методов / функций.

package codingpractice;

public class DuplicateCount {
public static void main(String argsp[]) throws Exception {
    int array[] = { 5, 1, 2, 5, 3, 2, 2, 5, 5 };
    DuplicateCount hw = new DuplicateCount();
    int length = hw.length(array);
    hw.duplicates(array, length);
}

public void duplicates(int array[], int length) throws Exception {

    int end =length, dupCount = 0;

    //copying to another array for later comparison
    int[] aarray = new int[length];
    for (int i = 0; i < end; i++) {
        aarray[i] = array[i];
    }

    //finding duplicates and removing the same
    for (int i = 0; i < end; i++) {
        for (int j = i + 1; j < end; j++) {
            if (array[i] == array[j]) {
                int shiftLeft = j;
                for (int k = j + 1; k < end; k++, shiftLeft++) {
                    array[shiftLeft] = array[k];
                }
                end--;
                j--;
            }
        }
    }

    //copying non duplicates to another array
    int[] tarray = new int[end];
    for (int i = 0; i < end; i++) {
        tarray[i] = array[i];

    }

    //Printing duplicates and there counts, comparing original array and non     duplicate array
    for (int i = 0; i < length(tarray); i++) {
        dupCount = 0;
        for (int j = 0; j < length; j++) {
            if (tarray[i] == aarray[j]) {
                dupCount++;
            }
        }
        if (dupCount > 1) {
            System.out.println(tarray[i] + " " + dupCount);
        }
    }
}

//length of array- not using inbuild function
int length(int array[]) throws Exception {
    int count = 0;
    int temp = 0;
    try {
        while (true) {
            count++;
            temp = array[count];
        }
    } catch (Exception e) {
        return count;
    }
}
}

3 ответа

Намного проще техника:

Map<Integer, Integer> map = new HashMap<>();
for (int i : array) {
    Integer count = map.get(i);
    if (count == null) {
        map.put(i, 1);
    }
    else {
        map.put(i, count.intValue() + 1);
    }
}
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
    if (entry.getValue() > 1) {
        System.out.println(entry.getKey() + " : " + entry.getValue());
    }
}

Для удовольствия, вот эквивалент Java 8:

Map<Integer, Integer> map = new HashMap<>();
for (int i : array) {
    map.compute(i, (k, v) -> (v == null) ? 1 : v + 1);
}

map.entrySet().stream()
              .filter(e -> e.getValue() > 1)
              .forEach(e -> System.out.println(e.getKey() + " : " + e.getValue()));

map.compute() вызов также может быть заменен

map.merge(i, 1, Integer::sum);

Просто чтобы дополнить решение JB Nizet для Java 7. Вот решение Java 8:

public static void main(final String[] args) throws Exception {
    final int[] ints = {1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 0, 0, 0};
    final Map<Integer, Integer> count = IntStream.of(ints).
            boxed().collect(HashMap::new, (map, i) -> {
        map.merge(i, 1, (j, k) -> j + k);
    }, HashMap::putAll);
    //to print out
    count.forEach((i, c) -> {System.out.println( i + " has a count of " + c);});
}

Выход:

0 has a count of 3
1 has a count of 2
2 has a count of 1
3 has a count of 2
4 has a count of 2
5 has a count of 1
6 has a count of 1
7 has a count of 1
8 has a count of 1
9 has a count of 1

Используя индексы, создайте пустой массив. Запустите ваш массив и увеличивайте соответствующее значение индекса каждый раз, когда вы запускаете его.

В вашем примере:

int[] source = { 5, 1, 2, 5, 3, 2, 2, 5, 5 };
int[] counts = new int[6];

for (int i : source) {
    counts[i]++;
}

Затем вы можете запустить счетчик, и вы получите каждый элемент (индекс массива) и его количество (значение массива).

Другие вопросы по тегам