Удалить строки в векторе - PullRequest
       5

Удалить строки в векторе

1 голос
/ 03 февраля 2012

У меня вектор, полный строк

вектор соответствияWords содержит 4 строки

  1. DEDF
  2. ФРЭЭ
  3. FEdF
  4. hedf

Теперь я хочу удалить все строки, слова которых не начинаются с буквы d

Однако в итоге мы просто удалили eedf и hedf, и в результате я получил

  1. DEDF
  2. FEdF

Мой код:

    for(int q=0; q<consistentWords.size(); q++)
    {
        string theCurrentWord = consistentWords[q];
        if(theCurrentWord[0] != 'd')
        {
            consistentWords.erase(consistentWords.begin()+q);
        }
    }

Есть мысли? Я просто не понимаю, почему он не удаляет все строки, которые не начинаются с d.

Ответы [ 6 ]

3 голосов
/ 03 февраля 2012

Начнем с того, что строки соответствуют этим индексам:

dedf 0
eedf 1
fedf 2
hedf 3

Допустим, вы удаляете eedf (поэтому q == 1. После удаления вектор выглядит как

dedf 0
fedf 1
hedf 2

Но затем q увеличивается до 2, полностью пропуская fedf. Исправление будет состоять в том, чтобы слегка изменить цикл for:

for(int q=0; q<consistentWords.size();)
{
    string theCurrentWord = consistentWords[q];
    if(theCurrentWord[0] != 'd')
    {
        consistentWords.erase(consistentWords.begin()+q);
    }
    else
    {
        q++;
    }
}

или что-то подобное.

3 голосов
/ 03 февраля 2012

Вы пропускаете элементы.Предположим, вам нужно удалить элементы 5,6: когда вы удаляете элемент 5, элемент 6 становится элементом 5 - и вы пропускаете его, поскольку q было увеличено до 6,

Лучший способ сделать это вручнуюувеличивается q только тогда, когда вы не удаляете элемент

2 голосов
/ 03 февраля 2012

Проблема в том, что вы удаляете элементы из вектора и увеличиваете свой индекс q в той же итерации.Итак, во 2-й итерации цикла for вы удаляете "eedf" из вектора, тогда ваш вектор равен ["dedf", "fedf", "hedf"] и q = 1.Но затем, когда вы возвращаетесь к началу цикла for, q увеличивается до 2, поэтому вы смотрите на "hedf" далее, пропуская "fedf".Чтобы это исправить, вы можете уменьшить q, когда удаляете элемент из массива, например:

for(int q=0; q<consistentWords.size(); q++)
{
    string theCurrentWord = consistentWords[q];
    if(theCurrentWord[0] != 'd')
    {
        consistentWords.erase(consistentWords.begin()+q);
        --q;
    }
}

Или вы можете использовать итераторы:

vector<string>::iterator it = consistentWords.begin()
while(it != consistentWord.end())
{
    string theCurrentWord = consistentWords[q];
    if(theCurrentWord[0] != 'd')
    {
        it = consistentWords.erase(it);
    }
    else
    {
        ++it;
    }
}

Обратите внимание, что erase возвращаетитератор элемента после того, который вы стерли.Вы должны переназначить it, потому что он становится недействительным при изменении размера вектора.

2 голосов
/ 03 февраля 2012

Когда вы стираете, вы не должны делать q ++.Тогда вы пропустите один элемент.

1 голос
/ 03 февраля 2012

На вопрос дан ответ, но вы должны посмотреть на Стереть-удалить идиому :

Пример:

consistentWords.erase(
    std::remove_if(consistentWords.begin(), consistentWords.end(), 
    [](const std::string& s) -> bool { return (s[0] == 'd'); }),
    consistentWords.end());
0 голосов
/ 03 февраля 2012

Удалить слово:

consistentWords.erase(
    std::remove(consistentWords.begin(), consistentWords.end(), theCurrentWord),
    consistentWords.end()
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...