我的程序正在寻找重复项。它将文件与文件夹和子文件夹中的每个其他文件进行比较。问题是,它正在重复检查。
例如,请考虑以下(粗略的)文件夹结构
-文件夹1
---文件1
---文件2
---文件3
-文件夹2
---文件1
---文件2
-文件夹3
---文件1
---文件2
---文件3
---文件4
因此,为了确保清晰,这意味着文件夹 1、文件夹 2 和文件夹 3 都位于根级别,每个文件夹中都有位于每个文件夹中的文件。
我的程序进行迭代,通过 2 个 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 循环并始终从下一次迭代开始,以防止搜索向后,但我不确定。在某一时刻,我认为冒泡排序可以有所帮助,但是,这与排序无关,尽管我可能可以或不能使用它。
我确信这种类型的问题已被记录并存在,我遇到的问题是(正如您可以从我的帖子的长度看出的)如何在 Google 搜索中描述,以便我可以研究是否存在某种模式存在。
所以,我的问题是,针对此类问题是否已经存在模式或范式?
最佳答案
您如何检测重复项?您只是查找重复的文件名,还是打开文件并读取内容?无论哪种方式,您都应该使用 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
}
}
这是一个未经测试的基本示例。您可以根据您的需要对其进行修改。您可以存储一个包含更多信息的类对象(根据您的需要进行自定义),而不是在哈希集中存储字符串。
无论如何,这个解决方案的时间复杂度为 O(n)
,而您的时间复杂度为 O(n^2)
。
关于c# - 我可以使用什么模式来确保我不会执行相同的操作两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16504948/