2011-03-30 67 views
6

我試圖找到字符串在那裏我有〜250萬串的向量的重複的實例的大載體複製〜檢查字符串中

目前我使用類似:

std::vector<string> concatVec; // Holds all of the concatenated strings containing columns C,D,E,J and U. 
std::vector<string> dupecheckVec; // Holds all of the unique instances of concatenated columns 
std::vector<unsigned int> linenoVec; // Holds the line numbers of the unique instances only 

// Copy first element across, it cannot be a duplicate yet 
dupecheckVec.push_back(concatVec[0]); 
linenoVec.push_back(0); 

// Copy across and do the dupecheck 
for (unsigned int i = 1; i < concatVec.size(); i++) 
{ 
    bool exists = false; 

    for (unsigned int x = 0; x < dupecheckVec.size(); x++) 
    { 
     if (concatVec[i] == dupecheckVec[x]) 
     { 
      exists = true; 
     } 
    } 

    if (exists == false) 
    { 
     dupecheckVec.push_back(concatVec[i]); 
     linenoVec.push_back(i); 
    } 
    else 
    { 
     exists = false; 
    } 
} 

這很好的小文件,但很明顯,最終以一個非常長的時間,文件大小的增長,由於嵌套的for循環和越來越多的包含在dupecheckVec字符串。

什麼可能是在一個大的文件要做到這一點不那麼可怕呢?

+0

您是否想過使用'unique'算法和'erase'? – lrm29 2011-03-30 13:50:27

+0

@ lrm29:獨特的要求矢量有序,這可能是或不是一個問題在這裏。 – 2011-03-30 14:10:49

+0

這就是爲什麼我沒有發佈它作爲答案。使用算法可能沒有發生OP。 – lrm29 2011-03-30 14:12:22

回答

8

如果你不介意重新排序的載體,那麼這應該做它在O(n*log(n))時間:

std::sort(vector.begin(), vector.end()); 
vector.erase(std::unique(vector.begin(), vector.end()), vector.end()); 

爲了維護秩序,你也可以使用的載體(行號,串*)對:按字符串排序,使用比較字符串內容的比較器唯一化,最後按照行號排序,如下所示:

struct pair {int line, std::string const * string}; 

struct OrderByLine { 
    bool operator()(pair const & x, pair const & y) { 
     return x.line < y.line; 
    } 
}; 

struct OrderByString { 
    bool operator()(pair const & x, pair const & y) { 
     return *x.string < *y.string; 
    } 
}; 

struct StringEquals { 
    bool operator()(pair const & x, pair const & y) { 
     return *x.string == *y.string; 
    } 
}; 

std::sort(vector.begin(), vector.end(), OrderByString()); 
vector.erase(std::unique(vector.begin(), vector.end(), StringEquals()), vector.end()); 
std::sort(vector.begin(), vector.end(), OrderByLine()); 
+0

非常感謝您的幫助代碼示例! – rbj 2011-03-30 14:10:38

5

你可以整理這是O(n LOGN),然後任何相等的元素必須是連續的,所以你可以只覈對了下一個元素,這是隻有O(N)。而你的天真解決方案是O(n^2)。

0

使用std::unique看到this

+5

,消除* *連續重複,不是所有重複。您需要首先對矢量進行排序以刪除所有重複項。 – 2011-03-30 13:55:31

+0

謝謝你,在我的腦後,卻沒有意識到。 – jonsca 2011-03-30 14:00:14

4

你可以使用它使用字符串作爲鍵和整數作爲值(計數)一個哈希表。然後,只需遍歷字符串列表和增量1。每個字符串值在哈希表最後迭代,並保持這些字符串以1

[更新] 另一種解決方案計數:

  • 使用散列表以字符串作爲載體/陣列
  • 字符串的鍵和索引位置對於向量中的每個字符串:
    • 如果字符串包含在哈希表[可選:刪除該條目並]繼續
    • 使用字符串作爲鍵,否則把當前字符串的索引位置爲哈希表,並繼續
  • 完成後疊代哈希表和使用索引檢索唯一字符串

該解決方案爲您提供了指數在所有字符串中,過濾出重複項。如果你只想要那些字符串,其中有沒有重複,你如果字符串在hastable已經用於去除散列表條目。

+0

@rbj:我更喜歡這一個關於接受的答案 - 使用hash_map這實際上很容易實現,並將幾乎O(n),這將顯着更快的250萬字符串.. – 2011-03-30 14:11:51