Удаление первых трех элементов 2d массива C ++ - PullRequest
0 голосов
/ 15 февраля 2020

Итак, вот моя проблема ... У меня есть 2d массив из 2 строк символов.

9D 5C 6S 9D KS 4S 9D
         9S

Если найдено 3, мне нужно удалить первые 3 на основе первого символа. карта Моя проблема в том, что я segfault почти во всем, что я делаю ... пул - это двумерный вектор

        selection = "9S";
        while(col != GameBoard::pool.size()  ){
            while(GameBoard::pool[col][0].at(0) == selection.at(0) || cardsRem!=0){
                if(GameBoard::pool[col].size() == 1){
                    GameBoard::pool.erase(GameBoard::pool.begin() + col);
                    cardsRem--;                        
                }
                else{
                    GameBoard::pool[col].pop_back();
                    cardsRem--;
                }
            }
            if(GameBoard::pool[col][0].at(0) != selection.at(0)){
                col++;
            }
        }

Я пробовал серию циклов for et c, и не повезло! Любые мысли спасут мое здравомыслие!

Поэтому я попытался вытащить сегмент кода, чтобы повторить его. Но я не могу ... Если я запусту всю свою программу в al oop, она в конечном итоге выдаст ошибку. Если я запускаю этот точный код в тех же обстоятельствах, это не так ... Я пытаюсь выяснить, что мне не хватает. Я вернусь, если выясню, где именно моя проблема ..

Так что, в конце концов, проблема не в самом моем коде, у меня есть утечки памяти или что-то, что в конечном итоге дополняется cra sh моя программа ... Как правило, каждый раз, когда я думаю, это один и тот же метод.

Ответы [ 2 ]

2 голосов
/ 15 февраля 2020

Более безопасный и эффективный способ удалить некоторые элементы из контейнера - применить идиому erase-remove .

Например, ваш фрагмент может быть переписан следующим образом (что тестируем здесь ):

using card_t = std::string;
std::vector<std::vector<card_t>> decks = {
    {"9D", "5C", "6S", "9D", "KS", "4S", "9D"},
    {"9S"}
};

card_t selection{"9S"};

// Predicate specifing which cards should be removed 
auto has_same_rank = [rank = selection.at(0)] (card_t const& card) {
    return card.at(0) == rank;
};

auto & deck = decks.at(0);

// 'std::remove_if' removes all the elements satisfying the predicate from the range
// by moving the elements that are not to be removed at the beginning of the range
// and returns a past-the-end iterator for the new end of the range.

// 'std::vector::erase' removes from the vector the elements from the iterator
// returned by 'std::remove_if' up to the end iterator. Note that it invalidates
// iterators and references at or after the point of the erase, including the
// end() iterator (it's the most common cause of errors in code like OP's). 
deck.erase(std::remove_if(deck.begin(), deck.end(), has_same_rank),
           deck.end());
0 голосов
/ 15 февраля 2020

Так что для любого в будущем, кто сталкивался с этим ... Проблема в том, что я удалял элемент из массива в al oop, с условной остановкой был его размер. Размер задан заранее, и хотя он учитывался в коде, он по-прежнему оставлял открытой возможность для while (array.size ()), который был бы заблокирован в 8 в l oop, обрабатываться как 6 в code.

Решением было сохранение местоположения в векторе для удаления, а затем удаление их за пределами l oop. Я думаю, что есть лучший, более технический ответ на этот вопрос, но он работает как задумано!

    for (double col = 0; col < size; ++col)
    {
        if(GameBoard::pool[col][0].at(0) == selection.at(0)){
                while(GameBoard::pool[col][0].at(0) == selection.at(0) && cardsRem !=0){
                    if( GameBoard::pool[col].size() > 1 ){
                        GameBoard::pool[col].pop_back();
                        cardsRem--;
                    }
                    if(GameBoard::pool[col].size() <2){
                        toDel.insert ( toDel.begin() , col );
                        //GameBoard::pool.erase(GameBoard::pool.begin() + col);
                        cardsRem--;
                        size--;
                    }
                }
        }
    }
    for(int i = 0; i< toDel.size(); i++){
        GameBoard::pool.erase(GameBoard::pool.begin() + toDel[i]);    
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...