2015-02-05 29 views
0

當我在此代碼中調用unique()時,輸出最終會添加最後一個元素的副本。unique()似乎要添加最後一個元素的另一個副本

vector<vector<int>> ints; 
for(int i(0); i<files; i++) 
{ 
    stringstream stream(list[i]); 
    int num(0); 
    vector<int> aList; 
    for(int j(0); j<list[i].length(); j++) 
    { 
     if(stream.peek() == ' ') 
       stream.ignore(); 
     while (stream >> num) 
     { 
      aList.push_back(num); 
      if(stream.peek() == ' ') 
       stream.ignore(); 
     } 
    } 
    ints.push_back(aList); 
    unique(ints[i].begin(), ints[i].end()); 
} 

我有一個字符串(這實際上是整數的列表)的矢量稱爲list正在解析成整數,並存儲在多維向量。 unique()意味着從創建的整數向量中去除重複項。

無論如何,我的問題是這樣的:我怎樣才能得到獨特的()來停止附加元素?

+1

它沒有在最後加上它們; *您不*除去重複,'std :: unique' *交換*在其算法期間結束。 'ints [i] .erase(std :: unique(ints [i] .begin(),ints [i] .end()),ints [i] .end);'。注意,你的流提取是格式化的,所以沒有理由啜泣周圍的空白。 – WhozCraig

+0

你應該看看它是如何工作的,因爲你沒有以正確的方式使用它:http://en.cppreference.com/w/cpp/algorithm/unique – Jack

+0

現在,我看着它,你可能會發現[像這樣的東西](http://pastebin.com/YKVbECLU)更簡單一點。 – WhozCraig

回答

2

如果你看一下std::unique的文檔,你會注意到它:

刪除所有連續重複元素從範圍[first,last)中並返回過去的最末端迭代器的新的邏輯結束範圍。

強調原創。返回僅在末尾應該是是 - 此算法實際上並沒有從容器中擦除任何元素,因爲它在一般情況下無法知道如何執行此操作。

這就是爲什麼你需要採取unique的結果,並將其傳遞到erase。從文檔中的例子:

auto last = std::unique(v.begin(), v.end()); 
v.erase(last, v.end()); 

或其它特殊情況:

ints[i].erase(
    // new logical end 
    std::unique(ints[i].begin(), ints[i].end()), 
    // actual end 
    ints[i].end()); 

還要注意的是unique只刪除連續重複 - 不所有重複。如果你真的想要獨特的結果,你首先需要sort你的載體。

+0

非常感謝!對不起,我花了一段時間才找回來。這解決了它。矢量是給我的排序,所以我不需要太擔心它。感謝您瞭解我的文檔。 –

1

您誤解了std::unique的功能。它不會刪除容器中的任何元素。它只是改變元素,使獨特的元素被推到前面。

它返回一個標記容器邏輯結束的迭代器。容器的物理末端保持不變。

容器的邏輯結束點和容器的物理結束點之間的元素具有未指定的值。

http://en.cppreference.com/w/cpp/algorithm/unique來自:

除去通過移動範圍中的元件以這樣的方式,要被擦除的元件被覆蓋來完成。保留的元素的相對順序被保留並且容器的物理尺寸不變。迭代器指向新邏輯結束和範圍的物理結束之間的元素仍然是可解引用的,但元素本身具有未指定的值。對唯一性的調用通常是在調用容器的擦除方法後,擦除未指定的值並減小容器的物理大小以匹配其新的邏輯大小。

相關問題