2

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

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

-文件夹 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 循环并始终从下一次迭代开始以防止搜索倒退,但我不确定。有一次,我认为冒泡排序可能会有所帮助,但这与排序无关,尽管我可以或不能使用它。

我确信这种类型的问题已记录并存在,我遇到的问题是(从我的帖子的长度可以看出)如何在谷歌搜索中描述,以便我可以研究是否存在模式。

所以,我的问题是,这样的问题是否已经存在模式或范式?

4

2 回答 2

2

您如何检测重复项?您只是在寻找重复的文件名,还是打开文件并阅读内容?无论哪种方式,您都应该使用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).

于 2013-05-12T07:08:30.080 回答
1
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          
    }

此代码在两个方面比您的代码执行得更好:

  1. 正如您所关心的,它不会对每对文件进行两次比较。
  2. 它只调用Directory.GetFile一次。
于 2013-05-12T07:11:54.313 回答