2015-09-23 2 views
2

У меня есть связанный список с некоторыми элементами.Как искать элементы 'n' впереди, итерации через список java?

{ (?i), \\d+, \\., \\d+, (?i), \\d+, \\. } 

Теперь, в то время как итерации, мне нужно выяснить, если три последовательных значения "\\d+", "\\.", "\\d+", если да, то мне нужно, чтобы объединить их в один узел со значением "\\d+\\.\\d+". Итак, мой предыдущий список должен выглядеть следующим образом после указанной операции.

{(?i), \\d+\\.\\d+, (?i), \\d+, \\.} 

Но, как Java не разоблачение связан внутренний класс узла Листом не существует никакого способа для меня, чтобы смотреть вперед более одного узла одновременно. Я мог бы заставить его работать со следующим кодом, но он выглядит уродливым для меня. Мне интересно, есть ли какой-либо чистый способ добиться того же.

LinkedList<String> l = new LinkedList<>(); //this can be ArrayList aswell. 
l.add("(?i)"); 
l.add("\\d+"); 
l.add("\\."); 
l.add("\\d+"); 
l.add("(?i)"); 
l.add("\\d+"); 
l.add("\\."); 
System.out.println(l.toString()); 
List<Integer> indexesToBeRemoved = new ArrayList<>(); 
for (int i = 0; i < l.size(); i++) { 
    int j = i; 
    if ("\\d+".equals(l.get(j))) { 
     j++; 
     if (j < l.size() && "\\.".equals(l.get(j))) { 
      j++; 
      if (j < l.size() && "\\d+".equals(l.get(j))) { 
       l.set(i, "\\d+\\.\\d+"); 
       indexesToBeRemoved.add(j); 
       indexesToBeRemoved.add(--j); 
      } 
     } 

    } 
} 

for (int i : indexesToBeRemoved) { 
    l.remove(i); 
} 

System.out.println(l.toString()); 

O/P: 
[(?i), \d+, \., \d+, (?i), \d+, \.] 
[(?i), \d+\.\d+, (?i), \d+, \.] 
+0

Невозможно использовать ArrayList? Потому что вы идете с индексированием – SacJn

+1

@SacJn Не имеет значения. LinkedList также имеет индексирование. – geekprogrammer

+0

Да, он имеет индексирование, но не эффективен, как ArrayList. Таким образом, любая операция на LinkedList потребляет гораздо больше времени, чем его счетная часть – SacJn

ответ

3

List.subList - твой друг, пользуй его.

List<String> pattern = Arrays.asList("\\d+", "\\.", "\\d+"); 
for(int i=0; i<=l.size()-pattern.size(); i++) { 
    List<String> subList = l.subList(i, i+pattern.size()); 
    if(subList.equals(pattern)) { 
     subList.clear(); 
     subList.add("\\d+\\.\\d+"); 
    } 
} 
System.out.println(l); 
+1

Мне очень нравится это решение, но если вы можете изменить жестко заданные вещи, такие как: 'i Flown

+0

@ Тагир Валеев. Genius. Спасибо за ответ. – geekprogrammer

+1

@Flown, pattern.size() - согласовано, отредактировано. 'String.join' - это функция Java-8 (текущее решение совместимо с Java-5), и в общем случае, вероятно, это не всегда должно быть заменено объединенным списком шаблонов, поэтому я оставил бы эту часть как есть. –

1

Если вы привязаны к использованию LinkedList, вы хотите использовать итератор, а не индексации, так как получить (п) является O (п) операции. Поскольку вы хотите иметь возможность вернуться назад, вы должны получить ListIterator из функции listIterator().

for(ListIterator<String> i = l.listIterator(); i.hasNext();){ 
    String element = i.next(); 
    if(element.equals("\\d+") && i.hasNext()) { 
     if(i.next().equals("\\.") && i.hasNext()) { 
      if(i.next().equals("\\d+")) { 
       i.remove(); 
       i.previous(); 
       i.remove(); 
       i.previous(); 
       i.set("\\d+\\.\\d+"); 
      } else { 
       i.previous(); 
       i.previous(); 
      } 
     } else { 
      i.previous(); 
     } 
    } 
} 

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

+0

На самом деле, я в порядке с Arraylist. Но, да, для LinkedList ваш ответ имеет больше смысла. – geekprogrammer

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