Эффективный способ подсчета уникальных пар в массиве int

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

Помещение: Я студентка первого курса ИТ.

Вот вопрос: я ищу эффективный способ подсчета количества уникальных пар (числа, которые появляются ровно дважды) в заданном положительном массиве int (это все, что я знаю), например. если:

int[] arr = {1,4,7,1,5,7,4,1,5};

число уникальных пар в arr равно 3 (4,5,7).

У меня есть некоторые трудности в ... оценке эффективности моих предложений, скажем так.

Вот первый код, который я сделал:

int numCouples( int[] v ) {
int res = 0;
int count = 0;
for (int i = 0 ; i < v.length; i++){
    count = 0;
    for (int j = 0; j < v.length; j++){
        if (i != j && v[i] == v[j]){
            count++;
        }
    }
    if (count == 1){
        res++;
    }
}
return res/2;
}

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

Это мой второй код:

int numCouples( int[] v) {
int n = 0;
int res = 0;
for (int i = 0; i < v.length; i++){
    if (v[i] > n){
        n = v[i];
    }
}
int[] a = new int [n];
for (int i = 0; i < v.length; i++){
    a[v[i]-1]++;
}
for (int i = 0; i < a.length; i++){
    if (a[i] == 2){
        res++;
    }
}
return res;
}

Я предполагаю, что это должно быть лучше первого, поскольку он проверяет только 2 раза данный массив и 1 раз на n массив, когда n является максимальным значением данного массива. Может быть, это не так хорошо, если я довольно большой, я думаю ...

Ну, 2 вопроса:

  1. Я понимаю, как «измерить» эффективность кода?

  2. есть лучший способ подсчитать количество уникальных пар в заданном массиве?

РЕДАКТИРОВАТЬ: Черт, я только что опубликовал, и у меня уже есть ответы! Благодаря! Я изучу каждого из них с осторожностью, пока я говорю, что я не получаю тех, кто связан с HashMap: из моих знаний еще (следовательно, снова спасибо за понимание: o))

1
Как 5 среди уникальной пары в вашем массиве примеров?
добавлено автор Rohit Jain, источник
@goet проверить мой ответ ниже, спасибо
добавлено автор goravine, источник
Я думаю, что с уникальными парами он означает числа, которые появляются ровно в два раза.
добавлено автор jlordo, источник
Что вы подразумеваете под уникальной парой?
добавлено автор Achintya Jha, источник
почему все хотят сортировать массив?
добавлено автор duffy356, источник
что вы имеете в виду с уникальными парами? я не понимаю, почему число «уникальных пар» не 4.
добавлено автор duffy356, источник
Вы можете реализовать свою собственную сортировку (сортировку вставки) и отслеживать дубликаты - и, следовательно, уникальные пары - когда вы идете
добавлено автор Bob Flannigon, источник
Извините, я исправил данный пример массива. С «уникальными парами» я имею в виду ... просто пару. Если есть более двух вхождений значения, это не считается «уникальной парой» (надеюсь, что это разъяснил, английский не мой язык натива извините) jlordo получил его! Я редактировал сообщение: o)
добавлено автор Goet, источник

6 ответы

public static void main(String[] args) {
    int[] arr = { 1, 4, 7, 1, 5, 7, 4, 1, 5 };

    Map map = new HashMap();

    for (int i = 0; i < arr.length; i++) {
        Integer count = map.get(arr[i]);
        if (count == null)
            map.put(arr[i], 1);
        else
            map.put(arr[i], count + 1);
    }

    int uniqueCount = 0;

    for (Integer i : map.values())
        if (i == 2)
            uniqueCount++;

    System.out.println(uniqueCount);
}
2
добавлено
public static void main(String[] args) {
    int[] arr = {1,4,7,1,7,4,1,5};
    Map counts = new HashMap();
    int count = 0;

    for(Integer num:arr){
        Integer entry = counts.get(num);

        if(entry == null){
            counts.put(num, 1);
        }else if(counts.get(num) == 1){
            count++;
            counts.put(num, counts.get(num) + 1);
        }
    }

    System.out.println(count);

}
1
добавлено
Ваш код может сломаться для тестового примера [5, 1, 4, 7, 1, 7, 4, 1, 5] . Он должен печатать 2 , тогда как ваш код печатает 4 .
добавлено автор sundar, источник
int [] a = new int [] {1, 4, 7, 1, 7, 4, 1, 5, 1, 1, 1, 1, 1, 1};
Arrays.sort (a);

int res = 0;
for (int l = a.length, i = 0; i < l - 1; i++)
{
    int v = a [i];
    int j = i + 1;
    while (j < l && a [j] == v) j += 1;
    if (j == i + 2) res += 1;
    i = j - 1;
}

return res;
1
добавлено
@BobFlannigon Любой вид сортировки будет более сложным по времени, чем подходы, основанные на хэш-таблице. Сортировка вставки - еще худший выбор, чем быстрый сортировка, независимо от повторного использования.
добавлено автор Marko Topolnik, источник
@jlordo О, он изменил вопрос. Код обновлен.
добавлено автор Mikhail Vladimirov, источник
@jlordo Неясно, что такое уникальная пара . В зависимости от значения массива «уникальная пара» {1, 1, 1, 1} может содержать 1, 2 или 6 «уникальных пар». Мой пример может быть легко изменен для реализации любого варианта, я просто выбрал значение, которое было проще реализовать.
добавлено автор Mikhail Vladimirov, источник
Smart, но не будет работать для int [] a = new int [] {1, 4, 7, 1, 7, 4, 1, 5, 1, 1, 1, 1, 1, 1};
добавлено автор jlordo, источник
@ Михайлов Владимирович: ОП расчистил то, что он имеет в виду. Он означает ровно два раза в массиве. Таким образом, в примере {1, 1, 1, 1} ответ будет равен 0.
добавлено автор jlordo, источник
Интеллектуальное решение.
добавлено автор Amir Pashazadeh, источник
Это не особенно эффективно, хотя нужно сортировать список, а затем прокручивать его и сравнивать все. Конечно, OP, вероятно, не волнует (а если нет, то +1 к этому), в противном случае объедините сортировку со счетчиком, чтобы уменьшить порядок операции (например, сортировку вставки)
добавлено автор Bob Flannigon, источник
Это работает и действительно разумно. Однако, насколько я понял, подход HashMap должен быть более эффективным ... но ему еще нужно учиться. Большие пальцы вверх по алгорифму!
добавлено автор Goet, источник

Ну, вот еще один ответ на ваши 2 вопроса:

am I understanding good how to "measure" the efficiency of the code?

Существуют различные способы измерения эффективности кода. Прежде всего, люди различают эффективность памяти и эффективность времени . Обычный способ подсчета всех этих значений - это знать, насколько эффективны строительные блоки вашего алгоритма. Посмотрите wiki .

Например, для сортировки с использованием quicksort понадобились операции n * log (n) . Итерирование через массив потребует только операций n , где n - количество элементов на входе.

there's a better way to count the number of unique pairs in a given array?

Вот еще одно решение для вас. Сложность этого будет: O (n * log (n) + n) , где O (...) - Знак Big O .

import java.util.Arrays;

public class Ctest {
  public static void main(String[] args) {
    int[] a = new int[] { 1, 4, 7, 1, 7, 4, 1, 5, 5, 8 };
    System.out.println("RES: " + uniquePairs(a));
  }

  public static int uniquePairs(int[] a) {
    Arrays.sort(a);
   //now we have: [1, 1, 1, 4, 4, 5, 5, 7, 7]

    int res = 0;
    int len = a.length;
    int i = 0;

    while (i < len) {
     //take first number
      int num = a[i];
      int c = 1;
      i++;

     //count all duplicates
      while(i < len && a[i] == num) {
        c++;
        i++;
      }
      System.out.println("Number: " + num + "\tCount: "+c);
     //if we spotted number just 2 times, increment result
      if (c == 2) {
        res++;
      }
    }

    return res;
  }
}
1
добавлено
Спасибо :) Наши алгоритмы действительно почти одинаковы, он сравнивает индексы, пока я суммирую события.
добавлено автор Ostap Andrusiv, источник
Принял этот ответ, потому что он единственный, кто пытается ответить на оба вопроса ...;), и алгоритм тоже очень умный (хотя я довольно редко предпочитаю реализацию Михаила Владимирова, но это примерно то же самое)
добавлено автор Goet, источник

вы можете использовать HashMap для легкой группировки. вот мой код.

int[] arr = {1,1,1,1,1,1,4,7,1,7,4,1,5};
    HashMap asd = new HashMap();
    for(int i=0;i

добавлено для проверки уникальной пары, вы можете удалить распечатку

//unique pair
    for(int key:asd.keySet())
    {
        if(asd.get(key) == 2)
        {
            System.out.println(key+" are a unique pair");
        }
    }
0
добавлено

через некоторое время другое решение, которое должно работать отлично.

public getCouplesCount(int [] arr) {
    int i = 0, i2;
    int len = arr.length;
    int num = 0;
    int curr;
    int lastchecked = -1;

    while (i < len-1) {
        curr = arr[i];
        i2 = i + 1;
        while (i2 < len) {
            if (curr == arr[i2] && arr[i2] != lastchecked) {
                num++;//add 1 to number of pairs
                lastchecked = curr; 
                i2++;//iterate to next
            } else if (arr[i2] == lastchecked) {
               //more than twice - swap last and update counter
                if (curr == lastchecked) {
                    num--;
                }
               //swap with last
                arr[i2] = arr[len-1];
                len--;
            } else {
                i2++;
            }
        i++;
    }

return num;
}

я не shure, если он работает, но он более эффективен, чем сортировка массива в первую очередь или использование hashmaps ....

0
добавлено
pro.jvm
pro.jvm
3 503 участник(ов)

Сообщество разработчиков Java Scala Kotlin Groovy Clojure Чат для нач-их: @javastart Наш сайт: projvm.com projvm.ru Наш канал: @proJVM Вакансии: @jvmjobs Конфы: @jvmconf

Java & Co
Java & Co
2 370 участник(ов)

Можно обсуждать с матом и без всё, что касается жабы, вплоть до холиваров. НЕ ИМЕЕТ ОТНОШЕНИЯ К САЙТУ JAVARUSH.RU ПРАВИЛА - https://t.me/javarush/75723 Вакансии сюда - https://telegram.me/joinchat/B7IzvUCnfo6d8t3yIxKguQ По вопросам - @thedude

learn.java
learn.java
1 888 участник(ов)

Чат для начинающих и не только Статистика: https://combot.org/chat/-1001083535868 Основной чат - @jvmchat

Java Underground
Java Underground
169 участник(ов)

https://vk.com/javatutorial

Javanese Questions
Javanese Questions
109 участник(ов)

Чат предназначен для обмена знаниями строго в формате в вопрос-ответ. Тема — Java, Kotlin и Android. Вопрос должен быть предварительно прогуглен, понятно и грамотно сформулирован, помечен хэштегами. Ответ — тем более. Куски кода размером в несколько строк можно писать прямо здесь, для больших кусков кода стоит использовать http://gist.github.com/, http://pastebin.com/, https://codeshare.io/ или любой аналогичный сервис. В некоторых случаях можно прикреплять скриншоты. Стикеры и гифки запрещены. Дополнять и уточнять вопросы и ответы — редактированием исходного сообщения. Обсуждения должны приводить к редактированию вопроса/ответа и удаляться. По хештегам можно искать существующие вопросы и овтеты: #вопрос #ответ #git #generics #java #server #awt #javafx #swing #kotlin #anko #tornadofx #ktor #android #recyclerView #performance #arch #network #permissions #storage #async