배열이 다른 배열의 부분 집합인지 확인
해당 목록이 다른 목록의 하위 집합인지 확인하는 방법에 대한 아이디어가 있습니까?
구체적으로, 나는
List<double> t1 = new List<double> { 1, 3, 5 };
List<double> t2 = new List<double> { 1, 5 };
LINQ를 사용하여 t2가 t1의 하위 집합인지 확인하는 방법은 무엇입니까?
bool isSubset = !t2.Except(t1).Any();
세트로 작업하는 경우 List 대신 HashSet을 사용하십시오. 그런 다음 간단히 IsSubsetOf () 를 사용할 수 있습니다
HashSet<double> t1 = new HashSet<double>{1,3,5};
HashSet<double> t2 = new HashSet<double>{1,5};
bool isSubset = t2.IsSubsetOf(t1);
LINQ를 사용하지 않아서 죄송합니다. :-(
목록을 사용해야하는 경우 @Jared의 솔루션은 존재하는 반복되는 요소를 제거해야한다는 경고와 함께 작동합니다.
당신이 경우 단위 테스트 당신은 또한 활용할 수 CollectionAssert.IsSubsetOf의 방법 :
CollectionAssert.IsSubsetOf(subset, superset);
위의 경우 이는 다음을 의미합니다.
CollectionAssert.IsSubsetOf(t2, t1);
확장 방법으로 @Cameron의 솔루션 :
public static bool IsSubsetOf<T>(this IEnumerable<T> a, IEnumerable<T> b)
{
return !a.Except(b).Any();
}
용법:
bool isSubset = t2.IsSubsetOf(t1);
(이것은 비슷하지만 @Michael의 블로그에 게시 된 것과 동일하지는 않습니다)
이것은 여기에 게시 된 다른 솔루션, 특히 최고의 솔루션보다 훨씬 효율적인 솔루션입니다.
bool isSubset = t2.All(elem => t1.Contains(elem));
t2에서 t1에없는 단일 요소를 찾을 수 있으면 t2가 t1의 하위 집합이 아님을 알 수 있습니다. 이 방법의 장점은 .Except 또는 .Intersect를 사용하는 솔루션과 달리 추가 공간을 할당하지 않고 모든 위치에서 수행된다는 것입니다. 또한이 솔루션은 하위 집합 조건을 위반하는 단일 요소를 찾은 후 다른 요소는 계속 검색하면서 중단 될 수 있습니다. 아래는 최적의 긴 형태의 솔루션이며 위의 속기 솔루션보다 테스트에서 약간 빠릅니다.
bool isSubset = true;
foreach (var element in t2) {
if (!t1.Contains(element)) {
isSubset = false;
break;
}
}
모든 솔루션에 대한 기본적인 성능 분석을 수행했으며 그 결과는 극적입니다. 이 두 솔루션은 .Except () 및 .Intersect () 솔루션보다 약 100 배 빠르며 추가 메모리를 사용하지 않습니다.
@Cameron 및 @Neil의 답변을 바탕으로 Enumerable 클래스와 동일한 용어를 사용하는 확장 메서드를 작성했습니다.
/// <summary>
/// Determines whether a sequence contains the specified elements by using the default equality comparer.
/// </summary>
/// <typeparam name="TSource">The type of the elements of source.</typeparam>
/// <param name="source">A sequence in which to locate the values.</param>
/// <param name="values">The values to locate in the sequence.</param>
/// <returns>true if the source sequence contains elements that have the specified values; otherwise, false.</returns>
public static bool ContainsAll<TSource>(this IEnumerable<TSource> source, IEnumerable<TSource> values)
{
return !values.Except(source).Any();
}
여기서 우리
t2
는 부모 목록 (iet1
)에 포함되지 않은 자식 목록 (ie ) 에 요소가 존재하는지 확인합니다 .없는 경우 목록은 다른 요소의 하위 집합입니다
예 :
bool isSubset = !(t2.Any(x => !t1.Contains(x)));
이 시도
static bool IsSubSet<A>(A[] set, A[] toCheck) {
return set.Length == (toCheck.Intersect(set)).Count();
}
여기서 아이디어는 Intersect가 두 배열에있는 값만 반환한다는 것입니다. 이 시점에서 결과 집합의 길이가 원본 집합과 동일하면 "set"의 모든 요소도 "check"에 있고 "set"은 "toCheck"의 하위 집합입니다.
참고 : "set"에 중복이 있으면 내 솔루션이 작동하지 않습니다. 나는 다른 사람들의 투표를 훔치고 싶지 않기 때문에 그것을 바꾸지 않습니다.
힌트 : Cameron의 답변에 투표했습니다.
참고URL : https://stackoverflow.com/questions/332973/check-whether-an-array-is-a-subset-of-another
'programing tip' 카테고리의 다른 글
Rails 4 스타일의 람다와 인수가있는 범위? (0) | 2020.06.20 |
---|---|
Ubuntu EC2 인스턴스에 EBS 추가 (0) | 2020.06.20 |
ID가 다른 테이블과 일치하지 않는 SQL 행 삭제 (0) | 2020.06.20 |
모범 사례 : 암호에 소금을 칠하고 후추를 바르는가? (0) | 2020.06.20 |
gradle로 소스 jar을 빌드하는 방법 (0) | 2020.06.20 |