2017-01-21 1 views
2

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

LinkedList<String> list = new LinkedList<String>(); 
list.add("A, B, C, D"); 
list.add("R"); 
list.add("A"); 
list.add("C, D"); 

Итак, наш LinkedList является: [ "A, B, C, D", "R", "A" ,"C, D" ]

Как вы можете видеть, "A" и "C, D" уже содержатся в "A,B,C,D".

Каков наиболее эффективный способ удаления содержащихся строк?

+0

Почему бы не использовать 'Set'? – CKing

+1

Набор не будет работать, для такой логики вы должны написать свою собственную реализацию. – nikowis

+2

Ваша структура данных нецелесообразна для этой цели. Рассмотрим сохранение значений как Set вместо строк CSV. – Bohemian

ответ

1

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

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

Во всяком случае, это простой метод, который может люкс:

private void deleteIfContains(LinkedList<String> list, String str) { 
    Iterator<String> headIterator = list.iterator(); 
    HashMap<Integer, String> newValues = new HashMap<>(); 
    int index = 0; 

    while (headIterator.hasNext()) { 
     String headString = headIterator.next(); 

     if (headString.contains(str)) { 
      headIterator.remove(); 
      //replace method won't handle ','..you will need to use regex for it 
      newValues.put(index, headString.replace(str, "")); 
     } 
     index++; 
    } 

    //Avoid ConcurrentModificationException 
    for (int i : newValues.keySet()) { 
     list.add(i, newValues.get(i)); 
    } 
} 
0

Я бы предложил использовать вместо этого Set, но вы должны были бы содержать каждое письмо в одной переменной String (возможно, вы должны использовать Character?).

Если вы действительно хотите придерживаться своей идеи, подумайте о том, чтобы реализовать свои собственные Set. Но сначала выяснить, что происходит в этой ситуации:

LinkedList<String> list = new LinkedList<String>(); 
list.add("A, B, C, D"); 
list.add("C, E"); 

C должен быть отвергнут, но как насчет E?

+0

Вы комментируете, что 'Set' не работает и продолжает отвечать на вопрос, говорящий, что используется' Set';) – CKing

+0

Любая существующая реализация набора не будет работать, как я заявил в комментарии, что пользовательская реализация может обрабатывать эту логику. – nikowis

+0

Вы сказали: * Я бы предложил вам использовать Set вместо *, а затем вы сказали * Если вы действительно хотите придерживаться своей собственной идеи *. Вы в основном говорите, что правильно используете «Set»? – CKing

0

Поскольку @nikowis говорит, что наилучшее решение зависит от определения проблемы.

Если значения являются элементами «A», «B», «C», «D», ... более эффективным решением (по времени вычисления) может быть преобразование списка в список> или один комплект.

Если значения являются «подстрокой», например «C, E» является значением ONE (а ​​не двумя «C» и «E»), вы можете использовать подстроку «Trie» (https://en.wikipedia.org/wiki/Trie). Он может быстро найти наличие подстроки в trie (O (log N) с N длиной добавляемой строки).

0

Преобразуйте строку csv-format в строковые значения. Затем сохраните их как заданный элемент. Если метод add() возвращает true, это означает, что значение уже присутствует.

String[] values = csvStr1.split(","); 
Set<String> hashSet = new HashSet<String>(Arrays.asList(values)); 

String[] values2 = csvStr2.split(","); 
for (String value: values2) { 
    if(hashSet.add(value) == true) { 
      //value already present. Ignore this or do whatever you want. 
    } 
} 
Смежные вопросы