查找&&删除for循环中的重复向量元素

时间:2015-10-24 21:11:52

标签: c++ vector duplicates

我将这些文件放在/etc/profile

root = Tk()

def change_text:
    testing.label['text'] = "New Text"

class MyGui:
    def __init__(self, master):
        frame = Frame(master)
        frame.pack()
        master.geometry("250x100") 
        master.wm_title("Register App")

        self.label = Label(frame, text="Original Text", fg="Black")
        self.label.grid(row = 0, column = 0, columnspan = 3)

        self.changeButton = Button(frame, text="Change Text", command=change_text)
        self.changeButton.grid(row = 2, column = 2)


testing = MyGui(root)
testing

列表中只剩下唯一的文件,即vector

vector<string> myFileNames ={"TestFile1","TestFile2","copiedFile1","copiedFile2","copiedFile3"};  

要填充重复的文件,即test file 1&2是重复的

vector<string> duplicateFilesFound;

填写copiedFile 1, 2 && 3哈希值

vector<string> myMd5Strings;

1 个答案:

答案 0 :(得分:0)

一个错误(可能还有其他错误)是你首先要测试MD5,但是你的内部k循环会错误地删除匹配哈希的第一个项目。例如,如果您的目标(i值)位于元素2,则您的循环不会检查k == 2是否跳过第一次出现。

测试应该是:

 if ( i != k && target == myMd5Strings[k])  

第二个问题是,如果删除某个项目,则需要将k值保持在原来的位置而不是递增。否则,如果匹配哈希值,您将跳过下一项检查并错过此项目。

但即使指出这些问题,你的尝试也是n^2的顺序 - 你有100个名字,即10,000次迭代,1,000个名字,1,000,000次迭代等等。最后,这个在大型名单上表现不佳。

下面提到的方法是对数(由于排序)及时,而不是二次方,因此对于大型列表大小执行速度要快得多。

但可以做一些结构性的改变。更好的方法是将文件名以及MD5哈希存储在单个结构中。然后声明这个结构的容器。

struct file_info
{
   std::string filename;
   std::string md5hash;
};
//...
std::vector<file_info> fInfoV;

一旦你有了这个,那么使用一些基本的算法函数,一切都变得非常简单。

要删除具有某个md5哈希值的重复项,可以先使用哈希值作为排序条件对列表进行排序,然后使用std::unique然后erase删除重复项。

   #include <algorithm>
   //...
   std::sort(fInfoV.begin(), fInfoV.end(), 
             [](const file_info&f1, const file_info& f2) 
             { f1.md5hash < f2.md5hash; });

   // uniqueify the vector
   auto iter = std::unique(fInfoV.begin(), fInfoV.end(), 
                           [](const file_info& f1, const file_info& f2) 
                           { f1.md5hash == f2.md5hash; });

   // for kicks, get the number of duplicates found
   auto duplicateCount = std::distance(iter, fInfoV.end());     
   cout << "There are " << duplicateCount << " duplicates found";

   // erase these duplicates
   fInfoV.erase(iter, fInfoV.end());

上面的代码,对重复项进行排序,统一和删除。我投入std::distance向您展示您可以获得重复数量,而无需创建另一个向量。上面的代码还克服了编写循环检查等效循环索引的需要,确保重新安装内部索引,检查边界等。

关于时间复杂性:

std::sort function保证具有对数复杂度 std::unique function具有线性复杂性:

所以这对于大型列表来说会更好。