2017-01-13 4 views
0

Так что я пытаюсь создать цикл for для поиска уникальных элементов в ArrayList. У меня уже есть ArrayList, который хранится с вводом пользователя из 20 мест (допускаются повторы), но я зациклился на том, как подсчитать количество разных мест, внесенных в список, за исключением дубликатов. (Я хотел бы избежать с помощью хэш)Как найти количество уникальных слов в списке массивов

Вход:

[park, park, sea, beach, town] 

Выход:

[Number of unique places = 4] 

Heres грубый пример кода я пытаюсь сделать:

public static void main(String[] args) { 

    ArrayList<City> place = new ArrayList(); 
    Scanner sc = new Scanner(System.in); 

    for(...) { // this is just to receive 20 inputs from users using the scanner 
    ... 
    } 

# This is where i am lost on creating a for loop... 

} 
+10

Почему бы вам не хотеть использовать хеш-набор? Это самый простой и, вероятно, самый эффективный способ решения этой проблемы. –

+0

Ха-ха, да, я знаю, но я искал его раньше, и я попробовал, но я действительно не понимаю, как использовать хэш очень четко. Поэтому я должен был использовать его и сам сценарий, я сомневаюсь, что могу четко объяснить, как это работает. – brand

ответ

1

Один из способов, который приходит на ум (без использования Set или hashvalues) состоит в том, чтобы сделать второй список.

ArrayList<City> places = new ArrayList<>(); 
//Fill array 

ArrayList<String> uniquePlaces = new ArrayList<>(); 
for (City city : places){ 
    if (!uniquePlaces.contains(city.getPlace())){ 
     uniquePlaces.add(city.getPlace()); 
    } 
} 

//number of unique places: 
int uniqueCount = uniquePlaces.size(); 

Обратите внимание, что это не очень эффективен = D

+0

Хорошо, это то, чего мне не хватало сделать второй список спасибо! Теперь я могу сравнить 2 списка, используя вложенный цикл for с условием if. – brand

+0

@brand - Нет, не используйте вложенный цикл. Просто используйте метод 'contains()' 'List'; он уже закодирован для вас и упакован в хороший метод. –

5

вы можете использовать набор для этого. https://docs.oracle.com/javase/7/docs/api/java/util/Set.html

Сохраните данные списка до Set. Set не будет иметь дубликатов, поэтому размер набора будет элементом без дубликатов.

использовать этот способ, чтобы получить установленный размер. https://docs.oracle.com/javase/7/docs/api/java/util/Set.html#size()

Образец кода.

 List<String> citiesWithDuplicates = 
       Arrays.asList(new String[] {"park", "park", "sea", "beach", "town"}); 
     Set<String> cities = new HashSet<>(citiesWithDuplicates); 

     System.out.println("Number of unique places = " + cities.size()); 
+0

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

+0

@TimBiegeleisen - Почему карта лучше, чем набор? –

+0

@TedHopp Тогда почему вы предложили использовать «HashSet» выше? –

1

Если вы не хотите использовать реализацию Set или Map интерфейсов (что позволит решить вам проблему с одной строки кода), и вы хотите, чтобы застрять с ArrayList, я предлагаю использовать что-то вроде Collections.sort() метода. Он сортирует элементы. Затем перебирайте отсортированный массив, сравнивайте и подсчитывайте дубликаты. Этот трюк может облегчить решение вашей итерационной задачи.

В любом случае, я настоятельно рекомендую использовать одну из реализаций интерфейса Set.

2

Если вы можете использовать Java 8, вы можете использовать distinct метод Java потоков:

int numOfUniquePlaces = list.stream().distinct().count(); 

В противном случае, используя set - это самое простое решение. Поскольку вы не хотите использовать «хеш», используйте TreeSet (хотя HashSet в большинстве случаев является лучшим решением). Если это не вариант, вам придется вручную проверять каждый элемент, является ли он дубликат или нет.

0

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

List<String> citiesWithDuplicates = Arrays.asList(new String[] { 
       "park", "park", "sea", "beach", "town", "park", "beach" }); 
     List<String> distinctCities = new ArrayList<String>(); 

     int currentIndex = 0; 

     for (String city : citiesWithDuplicates) { 
      int index = citiesWithDuplicates.lastIndexOf(city); 
      if (index == currentIndex) { 
       distinctCities.add(city); 
      } 
      currentIndex++; 
     } 
      System.out.println("[ Number of unique places = " 
      + distinctCities.size() + "]"); 
0

Ну, если вы не хотите использовать любые HashSets или подобные варианты, быстрый и грязный вложенными для цикла, как это, например, делает трюк (это просто медленно, как ад, если у вас есть много пунктов (20 будет просто прекрасным):

int differentCount=0; 
for(City city1 : place){ 
    boolean same=false; 
    for(City city2 : place){ 
     if(city1.equals(city2)){ 
     same=true; 
     break; 
     } 
    } 
    if(!same) 
     differentCount++; 
} 
System.out.printf("Number of unique places = %d\n",differentCount); 
+1

Да, своего рода медленный, но он решает проблему с созданием идеи второго списка и вложенным циклом, в котором он работал – brand

Смежные вопросы