어레이가 다른 어레이의 서브셋인지 확인합니다.
그 리스트가 다른 리스트의 서브셋인지 어떻게 확인할 수 있는지 아세요?
특히, 저는
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을 사용합니다.다음으로 IsSubset Of()를 사용할 수 있습니다.
HashSet<double> t1 = new HashSet<double>{1,3,5};
HashSet<double> t2 = new HashSet<double>{1,5};
bool isSubset = t2.IsSubsetOf(t1);
LINQ를 사용하지 않아 죄송합니다. :- (
목록을 사용해야 하는 경우 @Jared의 솔루션은 반복된 요소를 모두 제거해야 한다는 경고와 함께 작동합니다.
이는 여기에 게재되어 있는 다른 솔루션, 특히 상위 솔루션보다 훨씬 효율적인 솔루션입니다.
bool isSubset = t2.All(elem => t1.Contains(elem));
t2에서 t1에 없는 단일 원소를 찾을 수 있다면 t2는 t1의 부분 집합이 아니라는 것을 알 수 있습니다.이 방법의 장점은 를 사용하는 솔루션과는 달리 추가 공간을 할당하지 않고 모두 일괄적으로 수행된다는 것입니다.또는 제외.교차하다.또한 이 솔루션은 서브셋 조건을 위반하는 단일 요소를 발견하면 즉시 중단될 수 있으며 다른 요소는 검색을 계속할 수 있습니다.아래는 최적의 긴 형태의 솔루션으로, 위의 속기 솔루션보다 테스트 속도가 약간 더 빠릅니다.
bool isSubset = true;
foreach (var element in t2) {
if (!t1.Contains(element)) {
isSubset = false;
break;
}
}
모든 솔루션의 기본적인 퍼포먼스 분석을 실시했는데, 그 결과는 극단적입니다.이들 2개의 솔루션은 의 약 100배 고속입니다.예외()와cross() 솔루션을 사용하고 추가 메모리를 사용하지 않습니다.
유닛 테스트의 경우는, Collection Assert 를 사용할 수도 있습니다.IsSubset Of 메서드:
CollectionAssert.IsSubsetOf(subset, superset);
위의 경우 이는 다음을 의미합니다.
CollectionAssert.IsSubsetOf(t2, t1);
이 답변에서는 BenchmarkDotNet을 사용하여 3가지 실제 솔루션을 벤치마킹했습니다.
!t2.Except(t1).Any()
예외()를 호출했습니다.임의의()t2.IsSubsetOf(t1)
해시 세트라는 이름의t2.All(elem => t1.Contains(elem))
모두 호출(=> 포함)
3가지 파라미터가 있습니다.
- 슈퍼셋 수
- 부분집합 길이
- 항목의 변동성
모든 상위 집합이 임의 길이이며 범위에 포함된 항목입니다.[0; Variability)
. 서브셋은 길이가 일정하고 범위 내 아이템이 포함되어 있다.[0; Variability)
.
승자는 All(=> Contains) 메서드입니다.HashSet을 사용하는 경우보다 최대 30배, Except()보다 최대 50배 빠를 수 있습니다.임의의().
코드는 github에서 찾을 수 있습니다.
업데이트 @Gert Arnold의 코멘트에서 언급한 바와 같이 벤치마크에 버그가 있습니다.전화해봤어요.ToHashSet()
모든 반복의 내부.그래서 저는 또한 사전 빌드된 해시셋 컬렉션을 만들고, 다음과 같은 이름의 순수 해시셋 테스트를 추가했습니다.prebuilt HashSet
도 한다.All(=>Contains)
및인 것 .슈퍼셋의 가변성(및 중복성)이 포인트인 것 같습니다.값의 변동성이 낮으면 해시 집합이 데이터에서 제거되므로 해시 집합이 승리합니다.
마지막 표는 다음과 같습니다.
| Method | SupersetsInIteration | SubsetLength | Variability | Mean | Error | StdDev | Median |
|------------------- |--------------------- |------------- |------------ |--------------:|-------------:|-------------:|--------------:|
| Except().Any() | 1000 | 10 | 100 | 1,485.89 μs | 7.363 μs | 6.887 μs | 1,488.36 μs |
| ToHashSet() | 1000 | 10 | 100 | 1,015.59 μs | 5.099 μs | 4.770 μs | 1,015.43 μs |
| prebuilt HashSet | 1000 | 10 | 100 | 38.76 μs | 0.065 μs | 0.054 μs | 38.78 μs |
| All(=>Contains) | 1000 | 10 | 100 | 105.46 μs | 0.320 μs | 0.267 μs | 105.38 μs |
| Except().Any() | 1000 | 10 | 10000 | 1,912.17 μs | 38.180 μs | 87.725 μs | 1,890.72 μs |
| ToHashSet() | 1000 | 10 | 10000 | 1,038.70 μs | 20.028 μs | 40.459 μs | 1,019.35 μs |
| prebuilt HashSet | 1000 | 10 | 10000 | 28.22 μs | 0.165 μs | 0.155 μs | 28.24 μs |
| All(=>Contains) | 1000 | 10 | 10000 | 81.47 μs | 0.117 μs | 0.109 μs | 81.45 μs |
| Except().Any() | 1000 | 50 | 100 | 4,888.22 μs | 81.268 μs | 76.019 μs | 4,854.42 μs |
| ToHashSet() | 1000 | 50 | 100 | 4,323.23 μs | 21.424 μs | 18.992 μs | 4,315.16 μs |
| prebuilt HashSet | 1000 | 50 | 100 | 186.53 μs | 1.257 μs | 1.176 μs | 186.35 μs |
| All(=>Contains) | 1000 | 50 | 100 | 1,173.37 μs | 2.667 μs | 2.227 μs | 1,173.08 μs |
| Except().Any() | 1000 | 50 | 10000 | 7,148.22 μs | 20.545 μs | 19.218 μs | 7,138.22 μs |
| ToHashSet() | 1000 | 50 | 10000 | 4,576.69 μs | 20.955 μs | 17.499 μs | 4,574.34 μs |
| prebuilt HashSet | 1000 | 50 | 10000 | 33.87 μs | 0.160 μs | 0.142 μs | 33.85 μs |
| All(=>Contains) | 1000 | 50 | 10000 | 131.34 μs | 0.569 μs | 0.475 μs | 131.24 μs |
| Except().Any() | 10000 | 10 | 100 | 14,798.42 μs | 120.423 μs | 112.643 μs | 14,775.43 μs |
| ToHashSet() | 10000 | 10 | 100 | 10,263.52 μs | 64.082 μs | 59.942 μs | 10,265.58 μs |
| prebuilt HashSet | 10000 | 10 | 100 | 1,241.19 μs | 4.248 μs | 3.973 μs | 1,241.75 μs |
| All(=>Contains) | 10000 | 10 | 100 | 1,058.41 μs | 6.766 μs | 6.329 μs | 1,059.22 μs |
| Except().Any() | 10000 | 10 | 10000 | 16,318.65 μs | 97.878 μs | 91.555 μs | 16,310.02 μs |
| ToHashSet() | 10000 | 10 | 10000 | 10,393.23 μs | 68.236 μs | 63.828 μs | 10,386.27 μs |
| prebuilt HashSet | 10000 | 10 | 10000 | 1,087.21 μs | 2.812 μs | 2.631 μs | 1,085.89 μs |
| All(=>Contains) | 10000 | 10 | 10000 | 847.88 μs | 1.536 μs | 1.436 μs | 847.34 μs |
| Except().Any() | 10000 | 50 | 100 | 48,257.76 μs | 232.573 μs | 181.578 μs | 48,236.31 μs |
| ToHashSet() | 10000 | 50 | 100 | 43,938.46 μs | 994.200 μs | 2,687.877 μs | 42,877.97 μs |
| prebuilt HashSet | 10000 | 50 | 100 | 4,634.98 μs | 16.757 μs | 15.675 μs | 4,643.17 μs |
| All(=>Contains) | 10000 | 50 | 100 | 10,256.62 μs | 26.440 μs | 24.732 μs | 10,243.34 μs |
| Except().Any() | 10000 | 50 | 10000 | 73,192.15 μs | 479.584 μs | 425.139 μs | 73,077.26 μs |
| ToHashSet() | 10000 | 50 | 10000 | 45,880.72 μs | 141.497 μs | 125.433 μs | 45,860.50 μs |
| prebuilt HashSet | 10000 | 50 | 10000 | 1,620.61 μs | 3.507 μs | 3.280 μs | 1,620.52 μs |
| All(=>Contains) | 10000 | 50 | 10000 | 1,460.01 μs | 1.819 μs | 1.702 μs | 1,459.49 μs |
| Except().Any() | 100000 | 10 | 100 | 149,047.91 μs | 1,696.388 μs | 1,586.803 μs | 149,063.20 μs |
| ToHashSet() | 100000 | 10 | 100 | 100,657.74 μs | 150.890 μs | 117.805 μs | 100,654.39 μs |
| prebuilt HashSet | 100000 | 10 | 100 | 12,753.33 μs | 17.257 μs | 15.298 μs | 12,749.85 μs |
| All(=>Contains) | 100000 | 10 | 100 | 11,238.79 μs | 54.228 μs | 50.725 μs | 11,247.03 μs |
| Except().Any() | 100000 | 10 | 10000 | 163,277.55 μs | 1,096.107 μs | 1,025.299 μs | 163,556.98 μs |
| ToHashSet() | 100000 | 10 | 10000 | 99,927.78 μs | 403.811 μs | 337.201 μs | 99,812.12 μs |
| prebuilt HashSet | 100000 | 10 | 10000 | 11,671.99 μs | 6.753 μs | 5.986 μs | 11,672.28 μs |
| All(=>Contains) | 100000 | 10 | 10000 | 8,217.51 μs | 67.959 μs | 56.749 μs | 8,225.85 μs |
| Except().Any() | 100000 | 50 | 100 | 493,925.76 μs | 2,169.048 μs | 1,922.805 μs | 493,386.70 μs |
| ToHashSet() | 100000 | 50 | 100 | 432,214.15 μs | 1,261.673 μs | 1,180.169 μs | 431,624.50 μs |
| prebuilt HashSet | 100000 | 50 | 100 | 49,593.29 μs | 75.300 μs | 66.751 μs | 49,598.45 μs |
| All(=>Contains) | 100000 | 50 | 100 | 98,662.71 μs | 119.057 μs | 111.366 μs | 98,656.00 μs |
| Except().Any() | 100000 | 50 | 10000 | 733,526.81 μs | 8,728.516 μs | 8,164.659 μs | 733,455.20 μs |
| ToHashSet() | 100000 | 50 | 10000 | 460,166.27 μs | 7,227.011 μs | 6,760.150 μs | 457,359.70 μs |
| prebuilt HashSet | 100000 | 50 | 10000 | 17,443.96 μs | 10.839 μs | 9.608 μs | 17,443.40 μs |
| All(=>Contains) | 100000 | 50 | 10000 | 14,222.31 μs | 47.090 μs | 44.048 μs | 14,217.94 μs |
@Cameron의 솔루션 확장 방법:
public static bool IsSubsetOf<T>(this IEnumerable<T> a, IEnumerable<T> b)
{
return !a.Except(b).Any();
}
사용방법:
bool isSubset = t2.IsSubsetOf(t1);
(이것은 비슷하지만, @Michael의 블로그에 게재된 것과 전혀 다릅니다.)
@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();
}
2개의 2개의 배열이 .array1
★★★★★★★★★★★★★★★★★」array2
것을 하려고 합니다.array1
은 값에 있습니다.array2
:
array1.All(ar1 => array2.Any(ar2 => ar2.Equals(ar1)));
★★★★★★ar2.Equals(ar1)
평등을 다른 방법으로 설명할 경우 대체할 수 있습니다.
이거 드셔보세요
static bool IsSubSet<A>(A[] set, A[] toCheck) {
return set.Length == (toCheck.Intersect(set)).Count();
}
여기서의 개념은 교차점은 두 배열 모두에 있는 값만 반환한다는 것입니다.이 시점에서 결과 집합의 길이가 원래 집합과 동일한 경우 "set"의 모든 요소도 "check"에 있으므로 "set"은 "to Check"의 하위 집합입니다.
메모: "set"에 중복이 있으면 솔루션이 작동하지 않습니다.다른 사람의 표를 뺏고 싶지 않아서 바꾸는 게 아니에요.
힌트: 나는 카메론의 대답에 투표했다.
에서는 자목록에합니다( 자목록에 요소가 존재하는지 합니다).
t2
부모 「」)에 포함되지 않습니다( 「」( 「」).t1
하지 않는 는,
예:
bool isSubset = !(t2.Any(x => !t1.Contains(x)));
언급URL : https://stackoverflow.com/questions/332973/check-whether-an-array-is-a-subset-of-another
'it-source' 카테고리의 다른 글
ASP에서의 사용자 인증NET Web API (0) | 2023.04.21 |
---|---|
폴더가 존재하지 않는 경우 Bash를 사용하여 폴더를 작성하려면 어떻게 해야 합니까? (0) | 2023.04.21 |
Swift enum과 관련된 값의 동일성을 테스트하는 방법 (0) | 2023.04.21 |
Windows에서 Git으로 작업하도록 에디터를 설정하려면 어떻게 해야 합니까? (0) | 2023.04.21 |
SELECT DISTING이 지정된 경우 ORDER BY 항목이 선택 목록에 표시되어야 합니다. (0) | 2023.04.21 |