以前很少做刪除操作,vector一直當成數組用,而實際追求效率時又經常舍棄vector選用C風格數組。看《C++ Primer》到順序容器刪除這節時試着實現課后習題結果一動手我就出錯了。
習題是將數組int ia[]拷貝到std::vector<int>中,並刪除偶數元素。
先給出我的錯誤代碼
int ia[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89 };
vector<int> v(begin(ia), end(ia));
for (auto iter = v.begin(); iter != v.end(); ++iter)
{
if (!(*iter % 2))
v.erase(iter);
}
拋出異常:vector iterator not incrementable,迭代器不可遞增。
原因很簡單,因為迭代器都被刪除了……所以要用到erase函數的返回值來賦給iter,如果刪除成功則把那句v.erase(iter);改成iter = v.erase(iter);否則就直接++iter。
於是for循環第三部分沒什么用,干脆改成while循環,發現書上都有幾乎一模一樣的示例(好吧,畢竟書太厚,以為很熟悉的地方就一目十行了=。=)
更改后如下
int ia[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89 };
vector<int> v(begin(ia), end(ia));
auto iter = v.begin();
while (iter != v.end())
{
if (*iter % 2)
++iter;
else
iter = v.erase(iter);
}
這也體現了當年上數據結構時做課程作業馬虎的錯,當時實現基本數據結構時很多函數都沒實現完整,其實數據結構學好了容器也會很容易上手,因為了解了大致流程。
不用容器,直接刪除數組ia中的偶數,代碼如下
const unsigned cLength = 11;
unsigned size = cLength; // 數組新的大小
int ia[cLength] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89 };
int index = 0;
for (int n = 0; n < cLength; ++n) // n只代表訪問次數
{
if (ia[index] % 2)
index++;
else // 元素為偶數
{
--size; // 數組大小減1
// 被刪除元素后面的元素前移動
for (unsigned j = index; j < size; j++)
ia[j] = ia[j + 1];
// 元素下標不變
}
}
cout << "刪除后數組大小: " << size << "\n新的數組元素如下:\n";
for (int i = 0; i < size; i++)
cout << ia[i] << " ";
cout << endl;

