c# - 我可以使用什么模式来确保我不会执行相同的操作两次

标签 c# design-patterns

我的程序正在寻找重复项。它将文件与文件夹和子文件夹中的每个其他文件进行比较。问题是,它正在重复检查。

例如,请考虑以下(粗略的)文件夹结构

-文件夹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/

相关文章:

database - 在业务层过滤来自数据访问层的结果

.NET 工厂模式

scala - Akka 中的策略模式

c# - 如何获得浏览器渲染树的序列化(在 C# 中)

c# - 无法让 SignalR Hub 变量停止丢失值(静态变量不是问题)

c# - REST API 中对象的设计模式?

design-patterns - 这是对 Swift 原型(prototype)设计模式的正确使用吗?

c# - System.dll 中发生类型为 'System.Net.WebException' 的第一次机会异常

c# - FileSystemWatcher 在文件保存之前触发 - 你如何 "pause"这个过程?

c++ - 在 C++ 中,基类是否可以在所有派生类中调用虚拟方法?