Roger L
Roger L

Reputation: 11

removing a string from a vector C++

In any card game, you lose your card from your hand when you play it, but with my limited knowledge in vectors I can't do it. Tried to pushback then popback to get rid of the string from the vector but doesn't work.

//Create vector to store deck names in & player's hands
    vector<string> Cards;    
    vector<string> P1Hand;

//Generate the deck of cards
    for (int i = 0; i < SuitNum;i++) //iterate through suits
    { 
       for (auto j : CardValue)
        {
            card = j.first + suits[i]; //declare card
            DeckValue[card] = CardValue[j.first];//add card to deck map and assign value
            Cards.push_back(card);  // add card to vector
            CardNum++;// raise card number for every card added to deck
        }
    }

//display cards for player 1
        while (CardNum > 13)
        {
           int RCard = rand()%CardNum;//generate a random number based on number of cards left in deck
           string DrawCard = Cards.at(RCard); // access a random card
           P1Hand.push_back(DrawCard); //add card to hand
           Cards.erase(Cards.begin() + RCard); // remove cards from vector so they cant be called twice
           CardNum--; //lower available cards
           cout<<"["<<DrawCard<<"]"; //print card and its value
        }
        cout<<endl;
        cout<<"Select Card to Play: ",cin>>PlayedCardP1;

What I tried:

P1Hand.push_back(PlayedCardP1); //delete last card to next deck
P1Hand.pop_back();

Basically, PlayedCardP1 should be removed from P1Hand

Upvotes: 1

Views: 567

Answers (1)

JHBonarius
JHBonarius

Reputation: 11271

If you want to remove an item from a std::vector us an use std::vector::erase, like already used in the code. That function requires an iterator. Luckely, std::find, used for finding an element, gives you an iterator. Hence

P1Hand.erase(std::find(std::cbegin(P1Hand), std::cend(P1Hand), PlayedCardP1));

NB this invalidates iterators and references at or after the point of the erase, including the end() iterator. So take care it in an iterator loop. See the linked reference page.

Side note: std::vector is an array elements in memory. If you remove an element in the middle, all items after it will be shifted forward. That can become inefficient if done very often. An std::list is more efficient for that, but comes at the cost of more memory interactions when iterating and more storage for link pointers. You can test which one's better for you. You could also look at std::unordered_set, which only can contain each value once. But it has other issues. Always test which container works better.

p.s. for std::find you need to #include <algorithm>

Upvotes: 1

Related Questions