现状:
HashSet<string> MasterSet => {100, 3}
HashSet <string> SubSet => {100, 3} or {100} or {100, 3, 1}
因此,从庞大的子集列表中,基于MasterSet我选择了这样的特定集合:
if(MasterSet.SetEquals(subSet) || MasterSet.IsSupersetOf(subSet) || MasterSet.IsSubsetOf(subSet))
使用该子集进行处理(如果为true),否则循环遍历其他可用集。
重复问题: 如果业务逻辑想要在Master集和子集中包含副本,如:
MasterSet => {100, 3, 3}
SubSet => {100, 3, 3} or {100, 3} or {100, 3, 3, 1}
然后剥夺了HashSet的使用。
如果将MasterSet和Subset更改为List<string>
编辑: 解决方案由“BigYellowCactus”提供。但是,如果我想使用标题而不是元素的顺序来匹配,那么过滤集合会更容易吗?
MasterSet => {100, 3, 4}
MasterHeaders => {"T","F","V"} //Headers element corresponds to the MasterSet element
案例1:
SubSet => {3, 100}
SubSetHeaders => {"F", "T"} //Headers element corresponds to the SubSet element
案例2:
SubSet => {4, 3}
SubSetHeaders => {"V", "F"} //Headers element corresponds to the SubSet element
是否可以通过标题比较MasterHeaders和SubSetHeaders然后按值匹配来匹配?
答案 0 :(得分:1)
您可以使用All扩展程序。
<强>描述强>
确定序列的所有元素是否满足条件。
示例:强>
if (MasterSet.All(e => SubSet.Contains(e)) || SubSet.All(e => MasterSet.Contains(e)))
{
//do stuff
}
<强>替代:强>
if (!MasterSet.Except(SubSet).Any() || !SubSet.Except(MasterSet).Any())
{
//do stuff
}
修改强>
正如Iridium在评论中指出的那样,你想要SubSet { 100, 3, 3 }
而不是匹配MasterSet = { 100, 100, 3 }
,你可以简单地计算每个元素的发生。< / p>
if (MasterSet.All(e => MasterSet.Count(r => r==e) <= SubSet.Count(r => r==e))
|| SubSet.All(e => SubSet.Count(r => r==e) <= MasterSet.Count(r => r==e)))
{
//do stuff
}
(请注意,这可能不是最有效的方法......)
<强> EDIT2:强>
鉴于您基本上搜索序列内的序列,您可以使用以下方法:
void Main()
{
var MasterSet = new List<string>() {"100", "3","4"};
var SubSets = new[]
{
new List<string>() {"100", "100", "3"},
new List<string>() {"100", "3", "4"},
new List<string>() {"32", "3423", "4234", "100", "3", "4", "34234"},
new List<string>() {"100", "32", "3423", "4234", "100", "3", "4", "34234"},
new List<string>() {"100", "32", "3", "4234", "100", "4", "34234"},
new List<string>() {"100", "4", "3"},
new List<string>() {"100", "3", "3"},
new List<string>() {"100", "3"},
new List<string>() {"100", "3", "3", "1"}
};
foreach (var SubSet in SubSets)
{
if (IsMatch(MasterSet, SubSet))
Console.WriteLine(String.Join(", ", SubSet) + " is a \"subset\"");
else if (IsMatch(SubSet, MasterSet))
Console.WriteLine(String.Join(", ", SubSet) + " is a \"superset\"");
}
}
bool IsMatch<T>(IEnumerable<T> source, IEnumerable<T> to_test)
{
using (var enumerator = source.GetEnumerator())
using (var sub_enumerator = to_test.GetEnumerator())
while (sub_enumerator.MoveNext())
{
if (!enumerator.MoveNext())
return false;
if (!enumerator.Current.Equals(sub_enumerator.Current))
sub_enumerator.Reset();
}
return true;
}
<强>输出:强>
100,3,4是“子集”
32,3423,4234,100,3,4,34234是“超集”
100,32,3423,4234,100,3,4,34234是“超集”
100,3是“子集”
答案 1 :(得分:0)
ISet<T>
的当前框架实施是HashSet<T>
和SortedSet<T>
。这两个类都强制执行成员唯一性,并且不允许重复。
虽然这可能首先看起来像是框架中的遗漏,但它实际上与数学集的属性和定义有关。正如this post中所述,数学集不具有重复成员,而逻辑{100, 3}
等同于{100, 3, 3}.
可以将List<T>
扩展为实现ISet<T>
,也许可以调用新的类Sack<T>
但是,ISet<T>
的非唯一实现将极具挑战性对于那些在框架中存在的内容,如果不加以考虑,似乎对一般Knapsack problems有了回忆。