我有一个对象列表(实际上是一个ObservableCollection)(在我创建的类中定义的类型对象),每个对象都有自己的对象列表。 这是一个档案列表,每个档案都有一个档案列表。
如果设置了存档的“enabled”属性,我需要检查是否已经启用了另一个具有相同文件的存档。如果是这样,我需要做一些事情。
因此,如果我有(例如)1000个档案并且我启用了存档,我必须搜索每个档案的文件列表(= 1000个档案列表中的每个文件列表)以搜索匹配。
这是一个糟糕的实现吗?制作一个包含已启用的档案文件的额外列表会更好吗?或者也许是另一种做得更好的方式?
在归档类中定义列表并使其成为静态是不是一个好主意,或者我应该在使用列表的类中定义它(总是只有一个归档列表)
谢谢(newb试图通过练习来学习)
答案 0 :(得分:1)
与ObservableCollection<Archive>
一起,我可能会包含HashSet<File>
个。 (File
需要正确实施GetHashCode
和Equals
)这样可以让您快速查看文件是否已存在于任何其他档案中。
IList<Archive> archives = new ObservableCollection<Archive>();
ISet<File> files = new HashSet<File>();
void OnArchiveEnabled(Archive archive)
{
foreach (var file in archive.Files)
{
if (!files.Add(file))
{
//file already exists, do some stuff
}
}
}
我省略了OnArchiveEnabled
如何被触发(可能Archive.Files
属性为ObservableCollection<File>
),并且在此实现中无法禁用存档。要禁用存档,您可以重新创建files
集,或将files
更改为Dictionary<File, IList<Archive>>
(从文件到其所在的已启用存档的字典)并调整逻辑a位。
答案 1 :(得分:1)
这是一个糟糕的实施?
是的,因为它相当慢,O(N+M)
搜索查询的时间复杂度。
在归档类中定义列表是不是一个好主意......
我有更好的建议使用额外的索引。
弄清楚两个文件是否相同,例如:
根据步骤1中的匹配指标,您可以构建在步骤3中搜索的索引
制作快速索引是一件困难的事情。 fastes索引在O(1)
时间复杂度中起作用,这意味着如果查询它,它将以恒定时间返回结果,与归档和文件的数量无关。我首先要求这种表现。如果无法做到这一点,我会按排序顺序存储指标,这样您就可以在其上运行binary search
,但时间复杂度很快O(logN)
。
所以让我们尝试在O(1)中制作它。假设度量标准与文件名匹配(并不重要,纯粹为了简单起见)。字典数据结构允许您:
----------------------------------- Key | Value ----------------------------------- Foo.txt | Archive1, Archive43 Bar.txt | Archive2
注意:您必须保持索引的一致性,因此在对存档内容进行更改时更新索引。这可能会变得棘手!
现在是时候查询你的索引了!如果你按照步骤1和2进行操作,这很简单,只需要在字典中查询度量标准,得到结果。如果只有一个条目,那么它就是您的存档,如果有多个存档,那么您就知道哪个存档存储了同一个文件。