2017-02-26 51 views
-1

我知道這個標題很混亂,我只是用這麼幾個字來描述它。 考慮以下代碼:從矢量中刪除一個字符串<string>在矢量中定義的索引<int>

#include <vector> 
#include <string> 

using std::string; 
using std::vector; 

int main() { 
    vector<string> s = { "foo", "bar", "random_word" }; 
    vector<int> i = { 0, 1 }; 
    for (int n = 0; n < i.size(); n++) { 
     s.erase(s.begin() + (i[n])); 
    } 
} 

我想從另一個向量i的基礎上刪除索引矢量s的項目。實際的程序比這個更復雜,但是用幾句話來說,那個循環崩潰了(儘管它使用Visual C++編譯得很好)。

編輯:這是導致問題的實際代碼:

// The vector in which the elements to be deleted are defined consists of 
// { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 } (the 
// name is i) 
// The other vector (s) consists of 
// { "Bancheri", "Bertagna", "Buzzoni", "Canepa", "De Vita", "Di Bella", 
// "Drago", "Esposito", "Fossati", "Francini", "Frontini", "Lorenzi", 
// "Marusceac", "Miscio", "Padovani", "Scarfo'", "Sieni", "Thea Cioni", 
// "Zunino" }; 
} 
for (int p = 0; p < i.size(); p++) { 
     s.erase(s.begin() + (s[i])) 
} 

// This is how I fixed it: 

{ 
     int r = i.size() - 1; 
     while (r > 0) { 
      s.erase(s.begin() + i[r]); 
      r -= 1; 
     } 
} 

正如你所看到的,我只是做了其他環肚裏反向。

+2

你應該從更大的索引中刪除,以降低之一。 – Jarod42

+0

@ Rakete1111是的,現在修復了它 –

+3

你不初始化'n'? –

回答

3

這種方法的問題是,一旦i[n]的項目被刪除,它後面的所有索引就會移回一位。

爲了讓這個程序運行,排序i,並從最大到最小迭代。

+1

沒錯。 '的std ::排序(i.begin(),i.end(),標準::更大());'在進入循環之前。 – WhozCraig

+0

@WhozCraig我不知道這是什麼代碼的含義 –

+0

@TommasoTheaCioni它降序排列的容器。 –

0

正如已經指出的那樣,崩潰的原因是索引失效 - 在刪除i[n]的第th個元素後,所有大於i[n]的索引都必須減1。

通過以降序遍歷索引的容器,確保沒有在任何時刻比i[n]沒有索引更大,因此沒有必要調整其他索引,所以排序i沒有解決這個問題。

但是由於std::vector是一個連續的數組,因此逐個擦除元素通常不是一個好主意。根據你的情況,這也很容易重新排列的代碼來完成所有的擦除一氣呵成:

std::sort(i.begin(),i.end()); 
i.push_back(s.size()); //just to make sure the whole vector is visited 
auto iter = s.begin(); 
int current_index = 0; 
for(int index : i) 
{ 
    while(current_index < index) 
    { 
     *(iter++) = s[current_index++]; 
    } 
    current_index++; 
} 
s.erase(iter, s.end()); 

如果你能負擔得起代表元素,通過一定的值,例如被刪除一個空字符串,它變得更好:

for(int index : i) 
    s[index] = ""; 
s.erase(std::remove(s.begin(),s.end(),""),s.end()); 
相關問題