Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
197 views
in Technique[技术] by (71.8m points)

c++ - 从向量C ++中删除字符串(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

(基本上,应该从P1Hand中删除PlayedCardP1)

  ask by Roger L translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If you want to remove an item from a std::vector us an use std::vector::erase , like already used in the code.

(如果要从std::vector删除项目,请使用std::vector::erase ,就像代码中已经使用的一样。)

That function requires an iterator.

(该函数需要一个迭代器。)

Luckely, std::find , used for finding an element, gives you an iterator.

(幸运的是,用于查找元素的std::find为您提供了迭代器。)

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.

(注意,这将使擦除点或擦除点之后的迭代器和引用无效,包括end()迭代器。)

So take care it in an iterator loop.

(因此,请在迭代器循环中注意这一点。)

See the linked reference page.

(请参阅链接的参考页。)

Side note: std::vector is an array elements in memory.

(旁注: std::vector是内存中的数组元素。)

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.

(一个std::list对此更有效,但是以迭代时更多的内存交互和链接指针的更多存储为代价。)

You can test which one's better for you.

(您可以测试哪个更适合您。)

You could also look at std::unordered_set , which only can contain each value once.

(您还可以查看std::unordered_set ,它只能包含每个值一次。)

But it has other issues.

(但这还有其他问题。)

Always test which container works better.

(始终测试哪个容器效果更好。)

ps for std::find you need to #include <algorithm>

(ps for std::find您需要#include <algorithm>)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...