Лучшее решение, чтобы получить дубликаты и считать в массиве?
У меня есть код ниже, который нацелен на поиск дублирующегося элемента в массиве и печать его с его количеством.
Я использовал следующий подход для решения проблемы.
- скопировать исходный массив во временный массив
- найти дубликаты в исходном массиве и удалить тот же
- скопировать неповторяющийся массив в другой временный массив
- сравните массив без дубликатов с исходным массивом и распечатайте дубликаты с их количеством.
Для расчета длины я использую собственную версию кода.
Это о / п 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]++;
}
Затем вы можете запустить счетчик, и вы получите каждый элемент (индекс массива) и его количество (значение массива).