web-dev-qa-db-ja.com

インデックスで要素をstd :: vector <>から消去するにはどうすればいいですか?

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

std::vector<int> vec;

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

vec.erase(???);
430
dau_man

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

std::vector<int> vec;

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

// Deletes the second element (vec[1])
vec.erase(vec.begin() + 1);

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

// Deletes the second through third elements (vec[1], vec[2])
vec.erase(vec.begin() + 1, vec.begin() + 3);
590
mmmmmmmm

Std :: vectorのeraseメソッドはオーバーロードされているので、おそらく呼び出すほうが明確です。

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

一つの要素だけを消したいとき。

186
CodeBuddy
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);
}
49
Max

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
    
14
Eswaran Pandi

実際、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
6
Varun Garg

順序付けられていないベクトルがある場合は、順序付けされていないという事実を利用して、CPPCONのDan Higgins氏から見たものを使用できます。

template< typename TContainer >
static bool EraseFromUnorderedByIndex( TContainer& inContainer, size_t inIndex )
{
    if ( inIndex < inContainer.size() )
    {
        if ( inIndex != inContainer.size() - 1 )
            inContainer[inIndex] = inContainer.back();
        inContainer.pop_back();
        return true;
    }
    return false;
}

リストの順番は関係ありませんので、リストの最後の要素を削除したい項目の上にコピーしてから、最後の項目をポップして削除してください。

6
Clay J

もしあなたが大きなベクトル(サイズ> 100,000)を使っていてたくさんの要素を削除したいのなら、私はこのようなことをすることをお勧めします:

int main(int argc, char** argv) {

    vector <int> vec;
    vector <int> vec2;

    for (int i = 0; i < 20000000; i++){
        vec.Push_back(i);}

    for (int i = 0; i < vec.size(); i++)
    {
        if(vec.at(i) %3 != 0)
            vec2.Push_back(i);
    }

    vec = vec2;
    cout << vec.size() << endl;
}

コードは、3で割り切れないvec内のすべての番号を受け取り、それをvec2にコピーします。その後、vec2をvecにコピーします。かなり速いです。 20,000,000要素を処理するのに、このアルゴリズムは0.8秒しかかかりません。

Erase-methodでも同じことをしましたが、時間がかかります。

Erase-Version (10k elements)  : 0.04 sec
Erase-Version (100k elements) : 0.6  sec
Erase-Version (1000k elements): 56   sec
Erase-Version (10000k elements): ...still calculating (>30 min)
4
Fabian

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

// 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/

2
cammando

私はそれがあなたが探しているものだと信じているので、これを読むことをお勧めします。 https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom

たとえばを使用する場合

 vec.erase(vec.begin() + 1, vec.begin() + 3);

ベクトルのn番目の要素を消去しますが、2番目の要素を消去すると、ベクトルの他のすべての要素がシフトされ、ベクトルサイズは-1になります。これは、vector size()が減少しているため、vectorをループする場合に問題になる可能性があります。このような問題が発生した場合は、標準のC++ライブラリの既存のアルゴリズムを使用することをお勧めします。および「remove」または「remove_if」。

これが助けたことを願っています

1
explorer

これはどう?

void squeeze(vector<int> &v)
{
    int j = 0;
    for (int i = 1; i < v.size(); i++)
        if (v[i] != v[j] && ++j != i)
            v[j] = v[i];
    v.resize(j + 1);
}
0
def

これをvectorでの値で見つけて要素を削除したい場合は、これを行うもう1つの方法があります。これはvectorで行う必要があるだけです。

vector<int> ar(n);
ar.erase(remove(ar.begin(), ar.end()), (place your value here from vector array));

それはここからあなたの価値を取り除くでしょう。ありがとう

0
meenachinmay

前の答えは、あなたが always に符号付きインデックスを持っていると仮定しています。残念ながら、std::vectorはインデックス作成にsize_typeを、イテレータ演算にdifference_typeを使っているので、 "-Wconversion"が有効になっていて友達が有効になっている場合、それらは一緒に動作しません。これは、符号付きと符号なしの両方を処理できるようにしながら、質問に答えるもう1つの方法です。

削除する:

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;
}
0
Rian Quinn

最速の方法(時間の複雑さによるプログラミングコンテストの場合()=定数)

1秒で100Mアイテムを消去できます。

    vector<int> it = (vector<int>::iterator) &vec[pos];
    vec.erase(it);

そして最も読みやすい方法:vec.erase(vec.begin() + pos);

0
R.hatam