how to delete every third element from a vector

i have problem removing every third card from a vector (deck of cards) , where vector is of type "Card". the problem is that once an element is deleted from the vector the vector shifts its index position resulting in the wrong Card being deleted.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
 /*

Using command line arguments read in the file called Deck.txt
*/

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <fstream>

using namespace std;

//Enum types for Card objects

enum CardSuit { CLUBS, DIAMONDS, HEARTS, SPADES };

enum CardRank {ACE = 1, TWO, THREE ,FOUR, FIVE ,SIX, SEVEN , EIGHT, NINE, TEN, JACK , QUEEN, KING };

class Card
{
public:
	CardSuit suit;
	CardRank rank;


};





//Create two string arrays to use for overloaded operator << function
string ranks[] = { "", "Ace", "Two", "Three", "Four", "Five", "Six", "Seven",
"Eight", "Nine", "Ten", "Jack", "Queen", "King" };
string suits[] = { "Clubs", "Diamonds", "Hearts", "Spades" };

ostream& operator << (ostream & os, Card const& c) {

	os << ranks[c.rank] << " of " << suits[c.suit]; 
	return os; 


}

void print(vector<Card> const& v)
{

	for (size_t i = 0; i < v.size(); ++i)
	{
		cout << (i + 1) << "." << v[i] << endl; 

	}

	cout << endl; 


}



istream& operator >> (istream& is, Card& c)
{
	if (!is)
		return is;

	string rank, garbage, suit;
	is >> rank >> garbage >> suit;

	for (unsigned i = 1; i < (sizeof(ranks) / sizeof(ranks[1])); ++i)
	{
		if (rank == ranks[i])
			c.rank = CardRank(i);

		    //cout << c.rank << endl; 
	}

	for (unsigned i = 0; i < (sizeof(suits) / sizeof(suits[0])); ++i)
	{
		if (suit == suits[i])
			c.suit = CardSuit(i);
	}

	return is;
}

int main(int argc, char* argv[])
{
	ifstream infile(argv[1]);
	//Test for success
	if (!infile)
	{
		cerr << "Input file opening failed.\n";
		return	EXIT_FAILURE;
	}

	//Load a vector with the Card data 	
	vector<Card> deck;
	Card c;
	while (infile >> c)
	{
		deck.push_back(c);

	}

	print(deck); 

	

	// Remove every 3rd card from the deck. How many cards are left in the deck ?

	cout << "removing every 3rd card from the deck" << endl;

	vector<Card>::iterator it5 = deck.begin(); 


	for (int unsigned i = 0; i < deck.size(); ++i)
	{
		if (i % 3 == 2)
		{
			it5 = deck.erase(it5 + (i), it5 + (i)+1 );

			it5 = deck.begin(); 
			//++it5; 
		}

		/*
		else
		{
		   ++i; 
		}
		
		*/
	}


	cout << "deck after removing every third card " << endl; 

	print(deck);

	cout << "deck size after removing every third card " << deck.size() << endl;

	system("pause"); 



}


here is the entire deck of cards. u can save as txt file and use it to run through argv[1]:

Seven of Spades
Three of Clubs
Eight of Spades
Two of Spades
Two of Diamonds
Four of Clubs
Three of Diamonds
Six of Clubs
Nine of Diamonds
Four of Hearts
Five of Clubs
Three of Hearts
Ace of Diamonds
Six of Diamonds
Ace of Spades
Nine of Spades
Queen of Diamonds
Queen of Clubs
Five of Diamonds
Four of Diamonds
Seven of Hearts
Eight of Hearts
Queen of Hearts
Queen of Spades
Ten of Diamonds
Five of Hearts
Six of Hearts
Ten of Spades
Ten of Clubs
Five of Spades
Two of Hearts
Eight of Clubs
Four of Spades
Jack of Hearts
King of Hearts
Jack of Diamonds
Nine of Hearts
Eight of Diamonds
Jack of Clubs
Six of Spades
Nine of Clubs
Jack of Spades
Three of Spades
King of Diamonds
Seven of Diamonds
Ace of Hearts
Two of Clubs
Seven of Clubs
Ten of Hearts
Ace of Clubs
King of Clubs
King of Spades
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <vector>

// return a sequence with every nth element removed from a sequence container (n>0)
template < typename SEQ_CNTR > SEQ_CNTR remove_nth( const SEQ_CNTR& seq, std::size_t n )
{
    SEQ_CNTR result ;

    for( std::size_t i = 0 ; i < seq.size() ; ++i )
        if( i%n != (n-1) ) result.push_back( seq[i] ) ;

    return result ;
}

int main()
{
    std::vector<int> seq { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ;
    for( int v : seq ) std::cout << v << ' ' ;
    std::cout << '\n' ;

    seq = remove_nth(seq,3) ; // remove every third element from seq
    for( int v : seq ) std::cout << v << ' ' ;
    std::cout << '\n' ;
}

http://coliru.stacked-crooked.com/a/93cdd8c36a498680
Last edited on
is this the right aproach , how do i adjust my increment to account for the lost spot



for (int unsigned i = 0; i < deck.size(); ++i)
{
if (i % 3 == 2)
{
it5 = deck.erase(it5 + (i), it5 + (i)+1 );

it5 = deck.begin();
//++it5;
}

/*
else
{
++i;
}

*/
}
memory shuffling is more expensive that just doing a custom copy statement.
Copy into a new structure, and skip every 3rd one is probably the fastest way. There are a dozen other ways to do it, most require more coding and perform worse. I don't know if erase uses a memmove type approach or a copy to new approach.

Topic archived. No new replies allowed.