C# 对集合(非LINQ)的子集合执行布尔和字符串搜索
我希望这个标题有意义 我有一组C# 对集合(非LINQ)的子集合执行布尔和字符串搜索,c#,C#,我希望这个标题有意义 我有一组项目,我想根据一组关键字搜索并选择其中的一个子集,这些关键字必须在项目的任何子项目中至少出现一次。我相信使用LINQ很容易做到这一点,但我在这个项目中使用.NET2.0 假设实现了AllBitsAreSet,下面的代码应该可以实现我想要的功能,但是我想知道我是否缺少一种更简单的替代方法 由于除了循环检查位数组中的所有位(请告诉我是否有!)之外,似乎没有一种很好的方法来检查位数组中的所有位是否都已设置,因此我想知道“更好”的替代方法。不一定CPU效率更高,因为我怀疑下
项目
,我想根据一组关键字
搜索并选择其中的一个子集,这些关键字必须在项目
的任何子项目
中至少出现一次。我相信使用LINQ很容易做到这一点,但我在这个项目中使用.NET2.0
假设实现了AllBitsAreSet
,下面的代码应该可以实现我想要的功能,但是我想知道我是否缺少一种更简单的替代方法
由于除了循环检查位数组
中的所有位(请告诉我是否有!)之外,似乎没有一种很好的方法来检查位数组中的所有位是否都已设置,因此我想知道“更好”的替代方法。不一定CPU效率更高,因为我怀疑下面的代码对于我正在使用的数据集来说太慢,但是对于代码较少的数据集来说
public List<Item> Search(Item[] items, List<string> keywords)
{
List<Item> results = new List<Item>();
BitArray flags = new BitArray(keywords.Count);
foreach (Item item in items)
{
flags.SetAll(false);
foreach (SubItem subItem in item.SubItems)
{
for (int i = 0; i < keywords.Count; i++)
{
if (subItem.StringValue.IndexOf(keywords[i]) >= 0)
flags[i] = true;
}
}
if (AllBitsAreSet(flags)) results.Add(item);
}
return results;
}
公共列表搜索(项[]项,列表关键字)
{
列表结果=新列表();
BitArray标志=新的BitArray(关键字.Count);
foreach(项目中的项目)
{
flags.SetAll(false);
foreach(item.SubItems中的子项子项)
{
for(int i=0;i=0)
flags[i]=true;
}
}
如果(所有位设置(标志))结果。添加(项目);
}
返回结果;
}
您可以使用获取.NET 2.0上的LINQ支持,并使用以下LINQ查询
items.Where(i =>
keywords.All(k =>
i.SubItems.Any(s =>
s.StringValue.Contains(k))));
如果交换两个内部循环,可以避免使用位集-性能影响取决于子项的数量与关键字的数量
foreach (Item item in items)
{
Boolean found = false;
foreach (String keyword in keywords)
{
found = false;
foreach (SubItem subItem in item.SubItems)
{
if (subItem.StringValue.Contains(keyword))
{
found = true;
break;
}
}
if (!found)
{
break;
}
}
if (found)
{
result.Add(item);
}
}
我会这样写。当然,这与Daniel的解决方案非常相似,但我相信它更好
public List<Item> Search(Item[] items, List<string> keywords)
{
List<Item> results = new List<Item>();
foreach (Item item in items)
if(ContainsAllKeywords(item, keywords))
results.Add(item);
return results;
}
bool ContainsAllKeywords(Item item, List<string> keywords)
{
foreach (string keyword in keywords)
if (!ContainsKey(item.SubItems, keyword))
return false;
return true;
}
bool ContainsKey(IEnumerable<SubItem> subItems, string key)
{
foreach (SubItem subItem in subItems)
if (subItem.StringValue.Contains(key))
return true;
return false;
}
公共列表搜索(项[]项,列表关键字)
{
列表结果=新列表();
foreach(项目中的项目)
if(包含所有关键字(项目,关键字))
结果:增加(项目);
返回结果;
}
bool包含所有关键字(项目、列表关键字)
{
foreach(关键字中的字符串关键字)
如果(!ContainsKey(item.SubItems,关键字))
返回false;
返回true;
}
bool ContainsKey(IEnumerable子项,字符串键)
{
foreach(子项中的子项)
if(子项.StringValue.Contains(键))
返回true;
返回false;
}
编辑:根据注释将=
更改为.Contains()
一个项目可以有多少子项目?内部循环(对于int i=0)对我来说似乎是个问题。如果您提供示例输入/预期输出会更好。您的代码与Blix和Daniel的功能不同。您的代码检查subItem.StringValue和每个关键字之间是否完全匹配。它应该检查子字符串匹配。如果允许精确匹配,则可以进行更好的优化。例如,您可以将关键字作为键存储在字典中(或在.NET的更高版本中使用哈希集),这将给O(1)个查找时间。Luke,是的,这是一个错误,应该是。Contains()而不是==。谢谢你抓住了!我已经编辑了代码。然而,我不同意你关于使用字典/散列的评估。我知道散列查找是O(1),但我不知道如何在这种情况下直接应用它来提高性能。你能提供一个代码示例吗?谢谢你的评论。