我可以使用什么模式来确保我不会执行两次相同的操作?
本文关键字:两次 操作 执行 模式 什么 可以使 确保 我可以 | 更新日期: 2023-09-27 18:13:06
程序正在查找重复项。它将一个文件与文件夹及其子文件夹中的所有其他文件进行比较。问题是,它在重复检查。
例如,请考虑以下(粗略的)文件夹结构
-Folder1
——File1
——File2
——File3
-Folder2
——File1
——File2
-Folder3
——File1
——File2
——File3
——File4
因此,为了确保清晰,它意味着文件夹1,文件夹2和文件夹3都在根级别,在每个文件夹中都是每个文件夹中的文件。
我的程序遍历,通过两次foreach循环将每个循环与其他循环进行比较。
foreach (string path01 in Directory.GetFiles(SourcePath, "*.*", SearchOption.AllDirectories))
{
foreach (string path02 in Directory.GetFiles(SourcePath, "*.*", SearchOption.AllDirectories))
{
//perform logic with path01 and path02
}
}
现在,问题是其中一个迭代将比较Folder1'File1到Folder2'File1(这是期望的),但它也将比较Folder2'File1到Folder1'File1。这是低效的,因为检查已经完成了。现在我承认,只有我上面列出的文件/文件夹,可能会有人说谁在乎,但是我的应用程序要比较数千个文件夹,我不知道有多少文件。
在我的脑海中,我认为我必须按字母顺序排序,然后使用for循环,并始终在下一次迭代开始,以防止搜索向后,但我不确定。在某一点上,我认为冒泡排序可能会有所帮助,但是,这不是关于排序的,尽管可能我可以或不可以使用它。
我确信这种类型的问题是记录和存在的,我遇到的问题是,(你可以从我的文章的长度看出)如何在谷歌搜索中描述,这样我就可以研究是否存在模式。
所以,我的问题是,对于这样的问题是否已经存在一个模式或范式?
如何检测重复?您是只查找重复的文件名,还是打开文件并读取内容?无论哪种方式,都应该使用HashSet
var visitedFiles = new HashSet<String>();
foreach (string path01 in Directory.GetFiles(SourcePath, "*.*", SearchOption.AllDirectories)) {
String contents = // read in file contents
String contentHash = md5(contents); // do a md5 hash of the contents
if (!visitedFiles.contains(contentHash)) {
visitedFiles.add(contentHash);
} else {
// duplicate file found
}
}
这是一个基本的未测试示例。你可以根据自己的需要进行修改。您可以存储包含更多信息的类对象,而不是将string存储在hashset中(根据您的需要自定义它)。
无论如何,这个解的时间复杂度是O(n)
而不是你的O(n^2)
var files = Directory.GetFiles(SourcePath, "*.*", SearchOption.AllDirectories);
for (int i = 0; i < files.Length-1; i++)
for (int j = i+1; j < files.Length; j++)
{
string path1 = files[i];
string path2 = files[j];
//perform logic with path1 and path2
}
这段代码在两个方面比你的代码表现得更好:
- 它不比较每对文件两次,因为你关心。
- 只调用
Directory.GetFile
一次。