Проверьте, содержит ли строка элемент из списка (строк)

Так как это ваша домашняя работа, я не собираюсь давать вам ответ, но здесь есть хорошая визуализация бросания монет в питоне.

import matplotlib.pyplot as plt
import random
import numpy as np

number_of_toss=1000

def fairCoin():
    return random.choice([0,1])  

toss=[]
for i in range(number_of_toss):
    toss.append(fairCoin())    
    coins=np.bincount(np.array(toss))
    label=["heads","tails"]
    index = np.arange(len(label))
    if i>2:  
        Ph=np.around(coins[0].astype("float")/coins.sum().astype("float"),3)
        Pt=np.around(coins[1].astype("float")/coins.sum().astype("float"),3)
        plt.title("Heads:"+str(Ph)+"    Tails:"+str(Pt))
    plt.bar(index, coins)
    plt.xticks(index, label, fontsize=15)  
    plt.pause(0.05)

plt.show()
140
задан Dukeling 14 September 2017 в 15:32
поделиться

6 ответов

С LINQ, и использующий C# (я не знаю VB очень в эти дни):

bool b = listOfStrings.Any(s=>myString.Contains(s));

или (короче и более эффективный, но возможно менее ясный):

bool b = listOfStrings.Any(myString.Contains);

При тестировании равенства на это стоило бы посмотреть HashSet и т.д., но это не поможет с частичными соответствиями, если Вы не разделите его на фрагменты и добавляете порядок сложности.


обновление: если Вы действительно имеете в виду "StartsWith", то Вы могли отсортировать список и поместить его в массив; затем используйте Array.BinarySearch для нахождения каждого объекта - проверяют поиск, чтобы видеть, является ли это полное или частичное соответствие.

319
ответ дан 23 November 2019 в 23:13
поделиться

Было много предложений от более раннего подобного вопроса "Лучший способ протестировать на существующую строку против большого списка comparables".

Regex мог бы быть достаточным для Вашего требования. Выражение было бы конкатенацией всех подстрок кандидата, с ИЛИ"|"оператор между ними. Конечно, необходимо будет не упустить незавершенные символы при создании выражения или отказа скомпилировать его из-за ограничений размера или сложности.

Другой способ сделать это должно было бы создать trie структуру данных для представления всех подстрок кандидата (это может несколько копировать то, что regex matcher делает). Когда Вы ступаете через каждый символ в тестовую строку, Вы создали бы новый указатель на корень trie и усовершенствовали бы существующие указатели на соответствующего ребенка (если таковые имеются). Вы получаете соответствие, когда любой указатель достигает листа.

5
ответ дан 23 November 2019 в 23:13
поделиться

Я не уверен, более ли это эффективно, но Вы могли бы думать об использовании в Лямбда-выражениях.

1
ответ дан 23 November 2019 в 23:13
поделиться

Вы протестировали скорость?

т.е. Вы создали демонстрационный набор данных и представили их? Это не может быть настолько плохо, как Вы думаете.

Это могло бы также быть чем-то, что Вы могли породить прочь в отдельный поток и дать иллюзию скорости!

1
ответ дан 23 November 2019 в 23:13
поделиться

Если скорость является критической, Вы могли бы хотеть искать алгоритм Aho-Corasick для наборов шаблонов.

Это - trie со ссылками отказа, то есть, сложность является O (n+m+k), где n является длиной входного текста, m кумулятивная длина шаблонов и k количество соответствий. Просто необходимо изменить алгоритм для завершения после того, как первое соответствие будет найдено.

0
ответ дан 23 November 2019 в 23:13
поделиться

На основе Ваших шаблонов одно улучшение должно было бы измениться на использование StartsWith вместо, Содержит. StartsWith должны только выполнить итерации через каждую строку, пока она не находит первое несоответствие вместо того, чтобы иметь необходимость перезапустить поиск в каждой позиции символа, когда она находит тот.

Кроме того, на основе Ваших шаблонов похоже, что Вы можете извлекать первую часть пути для myString, затем инвертировать сравнение - поиск стартового пути myString в списке строк, а не наоборот.

string[] pathComponents = myString.Split( Path.DirectorySeparatorChar );
string startPath = pathComponents[0] + Path.DirectorySeparatorChar;

return listOfStrings.Contains( startPath );

Править: Это еще быстрее использовало бы идею HashSet @Marc упоминания Gravell, так как Вы могли измениться Contains кому: ContainsKey и поиск был бы O (1) вместо O (N). Необходимо было бы удостовериться, что пути соответствуют точно. Обратите внимание, что это не общее решение, как @Marc Gravell, но адаптируется в соответствии с Вашими примерами.

Извините за пример C#. У меня не было достаточного количества кофе для перевода в VB.

2
ответ дан 23 November 2019 в 23:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: