[C#] 문자열에 목록의 요소가 포함되어 있는지 확인하십시오 (문자열).

다음 코드 블록의 경우 :

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과 같은 수천 개의 문자열에 대해 점검해야합니다.

이 코드를 작성하는 더 나은 (더 효율적인) 방법이 있습니까?



답변

LINQ를 사용하고 C #을 사용합니다 (요즘 VB를 많이 알지 못합니다).

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

또는 (짧고 효율적이지만 분명하지는 않다) :

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

평등을 테스트하는 경우 HashSet등을 살펴볼 가치가 있지만 부분 일치로 조각을 나누고 복잡한 순서를 추가하지 않으면 부분 일치에 도움이되지 않습니다.


업데이트 : 정말로 “StartsWith”를 의미한다면, 목록을 정렬하여 배열에 넣을 수 있습니다. 그런 다음을 사용 Array.BinarySearch하여 각 항목을 찾으십시오. 전체 또는 부분 일치인지 확인하여 조회하십시오.


답변

문자열을 만들 때 다음과 같아야합니다

bool inact = new string[] { "SUSPENDARE", "DIZOLVARE" }.Any(s=>stare.Contains(s));


답변

이전의 비슷한 질문 ” 대규모 목록과 비교하여 기존 문자열을 테스트하는 가장 좋은 방법 “의 여러 제안이있었습니다 .

정규식이 요구 사항에 충분할 수 있습니다. 표현식은 모든 후보 서브 스트링을 연결하고 OR ” |“연산자를 사용합니다. 물론 표현식을 만들 때 이스케이프 처리되지 않은 문자를 보거나 복잡하거나 크기 제한으로 인해 컴파일에 실패해야합니다.

이 작업을 수행하는 또 다른 방법 은 모든 후보 하위 문자열을 나타내는 trie 데이터 구조 를 구성하는 것입니다 (정규 일치자가 수행하는 작업이 다소 중복 될 수 있음). 테스트 문자열에서 각 문자를 단계별로 살펴보면 trie의 루트에 대한 새 포인터를 만들고 기존 포인터를 해당 자식 (있는 경우)으로 이동시킵니다. 포인터가 잎에 도달하면 일치합니다.


답변

Marc의 답변이 마음에 들었지만 CaSe InSenSiTiVe가되기 위해서는 Contains 일치가 필요했습니다.

이것이 해결책이었습니다.

bool b = listOfStrings.Any(s => myString.IndexOf(s, StringComparison.OrdinalIgnoreCase) >= 0))


답변

패턴에 따라 포함 대신 StartsWith를 사용하도록 변경하는 것이 개선되었습니다. 모든 문자 위치를 찾을 때마다 검색을 다시 시작하지 않고 첫 번째 불일치를 찾을 때까지 각 문자열을 반복해야합니다.

또한 패턴을 기반으로 myString 경로의 첫 번째 부분을 추출한 다음 비교를 반대로하여 다른 방법이 아닌 문자열 목록에서 myString의 시작 경로를 찾는 것처럼 보일 수 있습니다.

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

return listOfStrings.Contains( startPath );

편집 : 이것은 변경할 수 있기 때문에 @Marc Gravell 언급 HashSet의 아이디어를 사용하여 더 빠른 것 Contains으로 ContainsKey하고 조회가 O (1) 대신 O (N)이 될 것입니다. 경로가 정확히 일치하는지 확인해야합니다. 이것은 @Marc Gravell의 일반적인 솔루션은 아니지만 예제에 맞게 조정되었습니다.

C # 예제가 유감입니다. VB로 번역 할 커피가 충분하지 않았습니다.


답변

오래된 질문입니다. 그러나 그 이후 VB.NET로 원래 요구 사항이있었습니다. 허용 된 답변과 동일한 값을 사용하십시오.

listOfStrings.Any(Function(s) myString.Contains(s))


답변

속도를 테스트 했습니까?

즉, 샘플 데이터 세트를 작성하고 프로파일 링했습니까? 생각만큼 나쁘지 않을 수 있습니다.

이것은 또한 별도의 스레드로 생성되어 속도의 환상을 줄 수있는 것일 수도 있습니다!