在向量对中按索引删除元素

时间:2017-01-17 20:14:19

标签: c++ vector std-pair

我在第一和第二位置都有矢量对整数,输入相当具体 首先,我有输入所有进入矢量的第一个点,但之后是第二个输入数组,它们应该进入第二个位置。
但是,我想做的是,我有一个条件,如果我发现第二个点的输入大于某个值(mana,在我的情况下变量),我想简单不要把它放到矢量对,并从第一个位置删除该索引上的第一个元素,我无法弄清楚如何编码它。 这是该代码的一部分:

vector<pair<int, int>>spellOne;

for (int i = 0; i < nSpellOne; i++)
{
    scanf_s("%d", &input);
    spellOne.back().first = input;
}

for (int i = 0; i < nSpellOne; i++)
{
    scanf_s("%d", &input);

    if (input > mana)
    {
        // removing the element on .first position at i index
    }
    else
    {
        spellOne.at(i).second = input;
    }
}

任何人都可以帮我解决如何做到这一点,如果可能,或者我应该切换到不同类型的数组? 我也考虑使用地图,但这是不可能的,因为我很有可能在矢量的第一个/第二个点中获得两次相同的值,因此我不能将它们中的任何一个用作关键字。

2 个答案:

答案 0 :(得分:2)

我做了一个例子,它应该让你得到提升以完成你的任务。在我的示例中,我填充向量,然后擦除具有大于某个阈值的第二个值的对(在这种情况下为2)。

现在你可以使用两个变量来跟踪擦除元素的循环,一个循环遍历整个向量,另一个用于跟踪要检查的当前索引;如果我们删除v[3],那么下一个元素v[4]会被移位(因为我们调用erase())代替v[3],因此我们应该再次检查索引3!

#include <iostream>
#include <utility>
#include <vector>

using namespace std;


int main()
{
    vector< pair<int, int> > v;
    int N = 5;
    const int threshold = 2;
    for(int i = 0; i < N; ++i)
        v.push_back(make_pair(i, i));

    int i = 0;
    while(i < v.size())
        if (v[i].second > threshold)
            v.erase(v.begin() + i);
        else
            i++;

    for(int i = 0; i < v.size(); ++i)
        cout << "(" << v[i].first << ", " << v[i].second << ")\n";

    cout << "Done" << endl;
}

输出:

(0, 0)
(1, 1)
(2, 2)
Done

编辑您的评论:您可以尝试:

int i = 0;
while(i < nSpellOne.size())
{
    scanf_s("%d", &input);
    if (input > mana)
        nSpellOne.erase(nSpellOne.begin() + i);
    else
        i++;
}

PS - 在编写高效代码时,不必担心std::cinscanf()是否更快,请关注您的算法!

答案 1 :(得分:1)

首先,用于加载向量的代码并不完全正确。

vector<pair<int, int>>spellOne;

for (int i = 0; i < nSpellOne; i++)
{
    int input1, input2;
    //scanf is C! Prefer C++ for doing input
    if(std::cin >> input1 >> input2)
        //Simply calling .back() presumes that an element already exists there, which in
        //the code you've provided, this isn't the case. emplace_back will allocate the 
        //memory correctly.
        spellOne.emplace_back(input1, input2);
    else
        break;//Could also do error handling here
}

std::vector不仅可以为您查询的任何元素神奇地留出空间:您必须专门使用将元素插入向量的方法,无论是emplace_back(理想),{ {1}},emplacepush_backinsert仅请求最后面的元素,如果相关元素不存在,或者您希望每次调用返回一个唯一元素,则会产生错误结果。

然后,当迭代向量时,正确使用STL将大大简化事情。

back

此代码对您的用例进行了少量更改,我们在第一个数字的同时提供第二个数字。因此,该程序的输入将为auto it = std::remove_if( spellOne.begin(), spellOne.end(), [mana](std::pair<int, int> const& data) { if(data.second > mana) return true; else return false; } ); spellOne.erase(it, spellOne.end()); 。如果你真的需要你之前的订单(虽然我不推荐它),这段代码可以正常工作,但会慢一些。

1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10