634

std::vector<int> があり、n 番目の要素を削除したいと考えています。それ、どうやったら出来るの?

std::vector<int> vec;

vec.push_back(6);
vec.push_back(-17);
vec.push_back(12);

vec.erase(???);
4

16 に答える 16

827

単一の要素を削除するには、次のようにします。

std::vector<int> vec;

vec.push_back(6);
vec.push_back(-17);
vec.push_back(12);

// Deletes the second element (vec[1])
vec.erase(std::next(vec.begin()));

または、一度に複数の要素を削除するには:

// Deletes the second through third elements (vec[1], vec[2])
vec.erase(std::next(vec.begin(), 1), std::next(vec.begin(), 3));
于 2009-05-17T18:01:45.087 に答える
315

std::vector の erase メソッドはオーバーロードされているため、おそらく呼び出す方が明確です

vec.erase(vec.begin() + index);

単一の要素のみを消去したい場合。

于 2009-05-17T18:08:55.853 に答える
62
template <typename T>
void remove(std::vector<T>& vec, size_t pos)
{
    std::vector<T>::iterator it = vec.begin();
    std::advance(it, pos);
    vec.erase(it);
}
于 2011-03-10T20:47:43.757 に答える
28

このeraseメソッドは、次の 2 つの方法で使用されます。

  1. 単一要素の消去:

    vector.erase( vector.begin() + 3 ); // Deleting the fourth element
    
  2. 要素の消去範囲:

    vector.erase( vector.begin() + 3, vector.begin() + 5 ); // Deleting from fourth element to sixth element
    
于 2016-05-04T11:06:07.913 に答える
13

実際、このerase関数は 2 つのプロファイルで機能します。

  • 単一の要素を削除する

    iterator erase (iterator position);
    
  • 要素の範囲を削除する

    iterator erase (iterator first, iterator last);
    

std::vec.begin() はコンテナの開始をマークするため、ベクトルの i 番目の要素を削除する場合は、次を使用できます。

vec.erase(vec.begin() + index);

よく見ると、vec.begin() はベクターの開始位置への単なるポインターであり、それに i の値を追加すると i 位置へのポインターがインクリメントされるため、代わりに次の方法で i 番目の要素へのポインターにアクセスできます。

&vec[i]

したがって、次のように記述できます。

vec.erase(&vec[i]); // To delete the ith element
于 2016-05-20T21:07:11.563 に答える
10

一部の人にとっては明らかなように思えるかもしれませんが、上記の回答を詳しく説明すると、次のようになります。

std::vectorベクター全体のループを使用して要素の削除を行っている場合はerase、ベクターを逆の順序で処理する必要があります。

for (int i = v.size() - 1; i >= 0; i--)

(クラシック)の代わりに

for (int i = 0; i < v.size(); i++)

その理由は、インデックスが影響を受けるeraseためです。4 番目の要素を削除すると、前の 5 番目の要素が新しい 4 番目の要素になり、実行している場合はループによって処理されませんi++

以下は、int ベクトルのオッズ要素をすべて削除したい場合の簡単な例です。

#include <iostream>
#include <vector>

using namespace std;

void printVector(const vector<int> &v)
{
    for (size_t i = 0; i < v.size(); i++)
    {
        cout << v[i] << " ";
    }
    cout << endl;
}

int main()
{    
    vector<int> v1, v2;
    for (int i = 0; i < 10; i++)
    {
        v1.push_back(i);
        v2.push_back(i);
    }

    // print v1
    cout << "v1: " << endl;
    printVector(v1);
    
    cout << endl;
    
    // print v2
    cout << "v2: " << endl;
    printVector(v2);
    
    // Erase all odd elements
    cout << "--- Erase odd elements ---" << endl;
    
    // loop with decreasing indices
    cout << "Process v2 with decreasing indices: " << endl;
    for (int i = v2.size() - 1; i >= 0; i--)
    {
        if (v2[i] % 2 != 0)
        {
            cout << "# ";
            v2.erase(v2.begin() + i);
        }
        else
        {
            cout << v2[i] << " ";
        }
    }
    cout << endl;
    cout << endl;
    
    // loop with increasing indices
    cout << "Process v1 with increasing indices: " << endl;
    for (int i = 0; i < v1.size(); i++)
    {
        if (v1[i] % 2 != 0)
        {
            cout << "# ";
            v1.erase(v1.begin() + i);
        }
        else
        {
            cout << v1[i] << " ";
        }
    }
    
    
    return 0;
}

出力:

v1:
0 1 2 3 4 5 6 7 8 9

v2:
0 1 2 3 4 5 6 7 8 9
--- Erase odd elements ---
Process v2 with decreasing indices:
# 8 # 6 # 4 # 2 # 0

Process v1 with increasing indices:
0 # # # # #

インデックスが増加する 2 番目のバージョンでは、偶数はスキップされるため表示されないことに注意してください。i++

逆の順序でベクトルを処理することにも注意してください。インデックスに符号なしの型を使用することはできません (動作for (uint8_t i = v.size() -1; ...しません)。これは、iequalsがオーバーフローして、たとえばと等しいためです (そのため、ループは停止せず、ベクトルの範囲外になる可能性があります)。0i--255uint8_ti>= 0

于 2020-08-26T13:27:54.150 に答える
3

要素を削除するには、次の方法を使用します。

// declaring and assigning array1 
std:vector<int> array1 {0,2,3,4};

// erasing the value in the array
array1.erase(array1.begin()+n);

より広範な概要については、http : //www.cplusplus.com/reference/vector/vector/erase/ をご覧ください。

于 2016-06-18T22:14:11.520 に答える
0

前の回答では、常に署名付きインデックスがあることを前提としています。悲しいことに、インデックス作成とイテレータ演算にstd::vector使用されるため、「-Wconversion」とフレンドが有効になっている場合、それらは一緒に機能しません。これは、署名付きと未署名の両方を処理できる一方で、質問に答える別の方法です。size_typedifference_type

削除する:

template<class T, class I, class = typename std::enable_if<std::is_integral<I>::value>::type>
void remove(std::vector<T> &v, I index)
{
    const auto &iter = v.cbegin() + gsl::narrow_cast<typename std::vector<T>::difference_type>(index);
    v.erase(iter);
}

取るには:

template<class T, class I, class = typename std::enable_if<std::is_integral<I>::value>::type>
T take(std::vector<T> &v, I index)
{
    const auto &iter = v.cbegin() + gsl::narrow_cast<typename std::vector<T>::difference_type>(index);

    auto val = *iter;
    v.erase(iter);

    return val;
}
于 2016-10-25T15:29:34.153 に答える