Для следующего блока кода:
For I = 0 To listOfStrings.Count - 1
If myString.Contains(lstOfStrings.Item(I)) Then
Return True
End If
Next
Return False
Выход:
Случай 1:
myString: C:\Files\myfile.doc
listOfString: C:\Files\, C:\Files2\
Result: True
Случай 2:
myString: C:\Files3\myfile.doc
listOfString: C:\Files\, C:\Files2\
Result: False
Список (listOfStrings) может содержать несколько элементов (минимум 20), и его нужно проверять на наличие тысяч строк (например, myString).
Есть ли лучший (более эффективный) способ написания этого кода?
источник
когда вы строите свои строки, это должно быть так
источник
Было несколько предложений от ранее подобного вопроса « Лучший способ проверить существующую строку по большому списку сопоставимых элементов ».
Regex может быть достаточно для вашего требования. Выражение будет объединением всех подстрок-кандидатов с оператором ИЛИ "
|
" между ними. Конечно, вам придется следить за неэкранированными символами при построении выражения или за невозможностью его компилировать из-за сложности или ограничений по размеру.Другим способом сделать это было бы создание структуры данных trie для представления всех подстрок-кандидатов (это может несколько дублировать то, что делает сопоставитель регулярных выражений). По мере продвижения по каждому символу в тестовой строке вы будете создавать новый указатель на корень дерева и продвигать существующие указатели к соответствующему дочернему элементу (если есть). Вы получаете совпадение, когда любой указатель достигает листа.
источник
Мне понравился ответ Марка, но мне нужно, чтобы соответствие Contains имело значение CASE INSENSiTiVe.
Это было решение:
источник
Основываясь на ваших шаблонах, одним из улучшений будет переход на использование StartsWith вместо Contains. StartsWith нужно только перебирать каждую строку до тех пор, пока не найдет первое несоответствие, вместо того, чтобы начинать поиск с каждой позиции символа, когда он ее найдет.
Кроме того, основываясь на ваших шаблонах, создается впечатление, что вы можете извлечь первую часть пути для myString, а затем отменить сравнение - искать начальный путь myString в списке строк, а не наоборот.
EDIT : Это было бы еще быстрее , используя идею HashSet @Marc Gravell упоминает , так как вы могли бы изменить ,
Contains
чтобыContainsKey
и поиск будет O (1) вместо O (N). Вы должны убедиться, что пути совпадают точно. Обратите внимание, что это не общее решение, как у @Marc Gravell, но оно адаптировано к вашим примерам.Извините за пример C #. У меня не было достаточно кофе, чтобы перевести на VB.
источник
Старый вопрос Но так как
VB.NET
было первоначальное требование. Используя те же значения принятого ответа:источник
Вы тестировали скорость?
т.е. вы создали образец набора данных и профилировали его? Это может быть не так плохо, как вы думаете.
Это также может быть что-то, что вы можете создать в отдельном потоке и создать иллюзию скорости!
источник
Если скорость критична, вы можете найти алгоритм Aho-Corasick для наборов паттернов.
Это три со ссылками на ошибки, то есть сложность O (n + m + k), где n - длина входного текста, m - совокупная длина шаблонов, а k - количество совпадений. Вам просто нужно изменить алгоритм, чтобы завершить работу после того, как найдено первое совпадение.
источник
источник
Недостаток
Contains
метода в том, что он не позволяет указать тип сравнения, что часто важно при сравнении строк. Он всегда чувствителен к культуре и регистру. Поэтому я думаю, что ответ WhoIsRich является ценным, я просто хочу показать более простую альтернативу:источник