std::vector<PROCESSSTRUCT>::iterator
От: Balsamo Россия  
Дата: 16.11.05 08:33
Оценка:
У меня вопрос.
Если я запоминаю итератор, указывающий на какой-то элемен в векторе, а потом этот лемент удаляю, то итератор должен стать некорректным. Это верно?
Ес да, то как тогда можно вытащить из вектора все элементы, удовлетворяющие необходимому условию, и вставить их в другой вектор, содержание которого соответвтвует условию?

Код примерно следующий:


typedef std::vector<PROCESSSTRUCT> QSystemQueue[32]; 

bool CSystemQueue::Recalculate()
{
...
      //Теперь размещаем процессы по очередям в зависимости от их приоритета
      for (uint i = 1; i <= 15; ++i)
    {
        if(!m_SystemQueue[i].empty() )
        {
            std::vector<PROCESSSTRUCT>::iterator cur;
            std::vector<PROCESSSTRUCT>::iterator last = m_SystemQueue[i].end();
            for (cur = m_SystemQueue[i].begin(); cur != last; ++cur)
            {
                uint prior = cur->ProcInfo.Priority.p_nice - cur->ProcInfo.Priority.p_cpu;
                //Здесь необходимо написать код для перемещения структуры из одной очереди в другую
                                          //Хотелось бы что-то наподобии такого:
                //----------------------------------------
                if (proir != i)
                {
                    m_SystemQueue[prior].push_back(cur);
                    m_SystemQueue[i].erase(cur);
                };
                 //----------------------------------------

            };
            
        };
    };
}

Я плохо еще общаюсь с STL, вот никак не могу понять, как лучше это сделать.
Re: std::vector<PROCESSSTRUCT>::iterator
От: alexeiz  
Дата: 16.11.05 09:29
Оценка:
Здравствуйте, Balsamo, Вы писали:

B>У меня вопрос.

B>Если я запоминаю итератор, указывающий на какой-то элемен в векторе, а потом этот лемент удаляю, то итератор должен стать некорректным. Это верно?
B>Ес да, то как тогда можно вытащить из вектора все элементы, удовлетворяющие необходимому условию, и вставить их в другой вектор, содержание которого соответвтвует условию?

Это можно сделать в три приёма. Сначала копируешь элементы из одного вектора в другой с помощью remove_copy_if, потом удаляешь в первом векторе элементы соответствующие твоему условию с помощью remove_if и наконец заканчиваешь удаление методом vector::erase. Вот пример:
#include <algorithm>
#include <functional>
#include <iostream>
#include <vector>

using std::vector;
using std::unary_function;
using std::not1;
using std::cout;
using std::ostream_iterator;
using std::endl;

struct pred : unary_function<int, bool>
{
    result_type operator()(argument_type x) const
    {
        return x < 6;
    }
};

int main()
{
    int a[] = {1,2,3,4,5,6,7,8,9,10};
    vector<int> v(a, a + sizeof(a)/sizeof(a[0]));
    vector<int> v2;

    remove_copy_if(v.begin(), v.end(), back_inserter(v2), not1(pred()));
    vector<int>::iterator last = remove_if(v.begin(), v.end(), pred());
    v.erase(v.begin(), last);

    copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
    cout << endl;
    copy(v2.begin(), v2.end(), ostream_iterator<int>(cout, " "));
    cout << endl;
}

Вывод:
6 7 8 9 10
1 2 3 4 5
Re[2]: std::vector<PROCESSSTRUCT>::iterator
От: alexeiz  
Дата: 16.11.05 09:38
Оценка:
Я тут немного ошибся, но благодаря удачно выбраным начальным данным пример отработал правильно

    v.erase(v.begin(), last);
нужно заменить на
    v.erase(last, v.end());
Re[3]: std::vector<PROCESSSTRUCT>::iterator
От: Balsamo Россия  
Дата: 16.11.05 10:12
Оценка:
Здравствуйте, alexeiz, Вы писали:

A>Я тут немного ошибся, но благодаря удачно выбраным начальным данным пример отработал правильно


A>
A>    v.erase(v.begin(), last);
A>
нужно заменить на

A>
A>    v.erase(last, v.end());
A>


Спасибо.
Re[2]: std::vector<PROCESSSTRUCT>::iterator
От: FR  
Дата: 16.11.05 11:22
Оценка:
Здравствуйте, alexeiz, Вы писали:


A>Это можно сделать в три приёма. Сначала копируешь элементы из одного вектора в другой с помощью remove_copy_if, потом удаляешь в первом векторе элементы соответствующие твоему условию с помощью remove_if и наконец заканчиваешь удаление методом vector::erase. Вот пример:


можно проще, разделить исходный вектор с помощью std::stable_partition (или std::partition если порядок не важен) нужную часть скопировать во второй вектор, и удалить в исходном:

[ccode]
#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <vector>

using std::vector;
using std::unary_function;
using std::cout;
using std::ostream_iterator;
using std::endl;

struct pred : unary_function<int, bool>
{
result_type operator()(argument_type x) const
{
return x < 6;
}
};

int main()
{
int a[] = {1,2,3,4,5,6,7,8,9,10};
vector<int> v(a, a + sizeof(a)/sizeof(a[0]));

vector<int>::iterator last = stable_partition(v.begin(), v.end(), pred());
vector<int> v2(v.begin(), last);
v.erase(v.begin(), last);

copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
cout << endl;
copy(v2.begin(), v2.end(), ostream_iterator<int>(cout, " "));
cout << endl;
}
[/code]
Re[2]: std::vector<PROCESSSTRUCT>::iterator
От: FR  
Дата: 16.11.05 11:25
Оценка: 1 (1)
Здравствуйте, alexeiz, Вы писали:


A>Это можно сделать в три приёма. Сначала копируешь элементы из одного вектора в другой с помощью remove_copy_if, потом удаляешь в первом векторе элементы соответствующие твоему условию с помощью remove_if и наконец заканчиваешь удаление методом vector::erase. Вот пример:


можно проще, разделить исходный вектор с помощью std::stable_partition (или std::partition если порядок не важен) нужную часть скопировать во второй вектор, и удалить в исходном:

#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <vector>

using std::vector;
using std::unary_function;
using std::cout;
using std::ostream_iterator;
using std::endl;

struct pred : unary_function<int, bool>
{
result_type operator()(argument_type x) const
{
return x < 6;
}
};

int main()
{
int a[] = {1,2,3,4,5,6,7,8,9,10};
vector<int> v(a, a + sizeof(a)/sizeof(a[0]));

vector<int>::iterator last = stable_partition(v.begin(), v.end(), pred());
vector<int> v2(v.begin(), last);
v.erase(v.begin(), last);

copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
cout << endl;
copy(v2.begin(), v2.end(), ostream_iterator<int>(cout, " "));
cout << endl;
}


(с форматированием промахнулся)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.