Как выполнить цикл для поиска одинаковых слов

#java

#java

Вопрос:

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

 String[] word = new String[] { "abcd", "efgh", "ijkl", "mnop" };
String[] word2 = new String[] { "ijkl", "rstu", "mnop" };

int totalWords = word.length;
int totalWords2 = word2.length;

//Use a List instead of array, because you don't know how many unique there are
List<String> uniqueWords = new ArrayList<>();

for (int i = 0; i < totalWords; i  ) { // loop of the first array list
boolean unique = false;

    for (int j = 0; j < totalWords2; j  ) { // second loop where the
                                        // words are being compared
    //compare String this way
        if (word[i].equals(word2[j])) {
        //we find two equals strings, it is unique
            unique = true;
            break;
        }
    }

    if (unique) {
        uniqueWords.add(word[i]);
    }
}

for (String s : uniqueWords) {
    System.out.println(s);
}   
  

и это работает и печатает

 ijkl 
mnop
  

Теперь я взял этот же код, применил его к своей проблеме и получил следующее, но это не работает. Он просто выводит мой точный список массивов. Я просто забочусь о сохранении номера индекса, где в списке есть одинаковые слова, но он печатается неправильно, поэтому я пока ничего не могу сохранить. Я неправильно подхожу к этой проблеме?

 //signatureList is my array list that i want to loop through to find words that are equal with each other
int o = signatureList.size();

      //Use a List instead of array, because you don't know how many unique there are
      List<String> uniqueWords = new ArrayList<String>();

      for (int i = 0; i < o; i  ) { // loop of the first array list
          boolean unique = false;

          for (int j = 1; j < o; j  ) { // second loop where the
                                                  // words are being compared
              //compare String this way
              if (signatureList.get(i).equals(signatureList.get(j))) {
                  //we find two equals strings, it is unique
                  unique = true;
                  break;
              }
          }


          if (unique) {
              uniqueWords.add(signatureList.get(i));
          }
      }

//prints out uniqueWords array list
      for(int i = 0; i < o ; i  )
            System.out.println("words that are equal "   uniqueWords.get(i));
  

Комментарии:

1. Почему бы вам не попробовать отладить свой код?

2. Ваш код не выполняет поиск всех равных слов, просто найдите одно и остановитесь…

Ответ №1:

 public static void main(String[] args) throws Exception {

    List<String> signatureList = new ArrayList<String>();
    signatureList.add("Test");
    signatureList.add("asdf");
    signatureList.add("jkjk");
    signatureList.add("Test");
    signatureList.add("1231");
    signatureList.add("asdf");
    signatureList.add("Test");

    Map<String,List<Integer>> locations = new HashMap<String,List<Integer>>();

    for (int i = 0; i < signatureList.size(); i  ) { 
        boolean unique = true;

        for (int j = 0; j < signatureList.size(); j  ) {

            if (i == j) {
                continue;
            }

            if (signatureList.get(i).equals(signatureList.get(j))) {
                unique = false;
                break;
            }

        }

        if (!unique) {

            if(locations.containsKey(signatureList.get(i))){
                List<Integer> intLocations = locations.get(signatureList.get(i));
                intLocations.add(i);
                locations.put(signatureList.get(i), intLocations);
            }else{
                List<Integer> intLocations = new ArrayList<Integer>();
                intLocations.add(i);
                locations.put(signatureList.get(i), intLocations);
            }
        }
    }

    for(Entry<String,List<Integer>> en : locations.entrySet()){
        System.out.print(en.getKey()   " : ");
        for(Integer i : en.getValue()){
            System.out.print(i   " ");
        }
        System.out.println();
    }
}
  

Дает мне вывод:

 Test : 0 3 6 
asdf : 1 5 
  

Полный исходный код для примера и тестирования. Обязательно пропустите сравнение с самим собой и не добавляйте в список, если он уже есть в списке.

Обновил мой ответ, чтобы он содержал решение для поиска индексов, в которых находятся совпадения.

Комментарии:

1. как вы думаете, я могу сохранить исходные индексы, в которых одинаковые слова были в списке подписей? Например, в вашем примере слово «Test» равно индексу 0 и 3, а «asdf» равно индексу 1 и 5. Как я могу сохранить эти индексы? Я предполагаю, что это должно быть в этом операторе if перед циклом for, который выводит одни и те же слова, но его сложно

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

Ответ №2:

Поскольку вам нужен только индекс, подумайте о том, чтобы сделать это, и вместо того, чтобы использовать логическое значение для определения его уникальности, просто добавьте индекс в arraylist , избавившись от ненужного оператора if, тем более, что его даже нет в правильном цикле for .

 ArrayList<Integer> uniqueWordsIndex = new ArrayList<Integer>();
if (signatureList.get(i).equals(signatureList.get(j))) {
              //we find two equals strings, it is unique
              uniqueWordsIndex.add(i)
              break;
          }
  

Ответ №3:

  for (int i = 0; i < o; i  ) { 
      boolean unique = false;

      for (int j = 1; j < o; j  ) { 

          if (signatureList.get(i).equals(signatureList.get(j))) {// the culprit is here
              //we find two equals strings, it is unique
              unique = true;
              break;
          }
      }
  

Приведенный выше код создает проблемы. signatureList.get(i).equals(signatureList.get(j) будет иметь значение true по крайней мере один раз для всех элементов signatureList . Итак, все элементы добавляются в ваш уникальный список.

Ответ №4:

В дополнение к комментариям есть еще одна проблема:

Вы должны сравнивать только два слова, если они имеют разный индекс. Если вы сравните слова с одинаковым индексом (i = j), конечно, все они будут включены в результат.

Ответ №5:

Я вижу две разные проблемы: во-первых, вам не нужно выполнять эту проверку, если i == j , поэтому делайте это только тогда, когда они разные. Вы можете сохранить проверку equals, просто иметь unique быть числом и установить его равным нулю вместо false, а затем увеличить это значение. Если unique > 1 затем добавьте его в свой список, поскольку вы нашли дубликат.

Кроме того, избавьтесь от ненужной проверки unique .

           if (signatureList.get(i).equals(signatureList.get(j))) {
              //we find two equals strings, it is unique
              unique = true;
              uniqueWords.add(signatureList.get(i));
              break;
          }
  

В этом цикле for o не была установлена длина уникального списка, поэтому вы получите сообщение об ошибке, когда ваша проблема будет устранена.

   for(int i = 0; i < o ; i  )