Random sorting within array

I have an array of std::strings I need to sort into random order. The thing is that no element can be repeated. To do this, I thought I would remove each element that is sorted out of the array, to keep it from repeating, but I don't know of any function to do that without just leaving a void in the array. Does anyone know of a way to do this?

Fafner
What do you mean "sort into random order"? That comes quite close to being contradiction if it isn't one already.

If you want to sort your strings and eliminate duplicates at the same time... why not an std::set? It automatically sorts any data put into it, and refuses to accept duplicates.
http://cplusplus.com/reference/stl/set/

Edit: if by sort into random order you mean mix up the values of the elements in your array randomly, then eliminate the duplicates first (you can do this by comparing the elements in your array with each other), then write a function that swaps the positions of two elements in the array.

-Albatross
Last edited on
Well, for example, if I had the array 1, 2, 3, 4, 5, 6
Then I would want to have it sorted into, say, 3, 6, 4, 1, 5, 2

But thanks, I'll check out sets, I wasn't aware of them ;)
Ah... then check my edit in my other post. Note that you could use rand() to determine which elements to swap... but you knew that.

-Albatross

EDIT: std::cout << pow(2,0) << pow(2,1) << pow(2,2) << pow (2,3) << " posts, and counting.";
Last edited on
haha, just saw your edit;)

Ok, so I tried to write a function, but naturally it segfaults=P If you would take a look it would be greatly appreciated:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Deck newShuffledDeck(void) {
	std::string values[] = {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Knight", "Queen", "King"};
	std::string versions[] = {"Clubs", "Spades", "Hearts", "Diamonds"};
	Deck d;
	int vSize = 13;
	for (int i = 0; i < 3; i++) {
		for(int c = 0; c < 12; c++) {
			int vSel = rand()%vSize;
			Card c(values[rand()%vSel], versions[i]);
			for (int i = vSel; i < vSize; i++) {
				values[i] = values[i+1];
			}
			vSize--;
			d.push_back(c);
		}
	}
	return d;
}


As you can see, I'm trying to shuffle a deck of cards;)
Oh... so... oh... that's even easier.

First off, line 11 looks suspicious, but... it should work... egh, I recommend the use of vectors over arrays, because they have a function just for doing what you want to do.
http://cplusplus.com/reference/stl/vector/erase/

Second... maybe the problem is in your Deck? Again, if you're using arrays there, maybe you'd like to consider vectors.

EDIT:
Third... ooooh boy. Lines 7 and 9. Do you see the problem?
Fourth, the bounds for the for loop at line 6 are off. Do you see why?
Fifth, consider using j as the interated integer for the for loop starting at line 10.

-Albatross
Last edited on
@Albatross
EDIT: std::cout << pow(2,0) << pow(2,1) << pow(2,2) << pow (2,3) << "posts, and counting.";

error C2668: 'pow' : ambiguous call to overloaded function :)
Great, thanks;) I tried vectors in the beginning though, and my compiler didn't like these lines:

1
2
std::vector<std::string> values = {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Knight", "Queen", "King"};
std::vector<std::string> versions = {"Clubs", "Spades", "Hearts", "Diamonds"};


I could of course create each string and then push_back it, but is there a more efficient way?

EDIT: Haha, I just saw your last edit, that was stupid of me to name the int and card the same=P But why are the bounds at line 6 off? And Deck is just:
typedef std::vector<Card>Deck
And Card contains vectors;)
Last edited on
@R0mai:
See, I don't get that error when compiling that line. I get the error
/Users/albatross/Documents/testpad/main.cpp:1:0 /Users/albatross/Documents/testpad2/main.cpp:1: error: 
expected constructor, destructor, or type conversion before '<<' token


@fafner:
You go through only three of the versions, and that's why the bounds are off. Did you mean i <= 3?
And the shorter (textwise) way is to create an extra array with those values, and use assign(). There's probably a shorter way but my brain is running low on caffeine.

http://cplusplus.com/reference/stl/vector/assign/

Note the third comment on the code snippet.

-Albatross
Last edited on
@Albatross
OK, call it even, it doesn't compile either way :)
In order to do this:

std::vector<std::string> values = {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Knight", "Queen", "King"};

You could do this:

1
2
3
4
5
6
7
const char* card_data[] =
{
	"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10"
	, "Knight", "Queen", "King"
};

std::vector<std::string> card_list(card_data, card_data + (sizeof(card_data)/sizeof(char*)));
Thanks for all your help folks! My code currently looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Deck newShuffledDeck(void) {
	srand(clock());
	std::string vals[] = {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"};
	std::string vers[] = {"Clubs", "Spades", "Hearts", "Diamonds"};
	std::vector<std::string> values;
	std::vector<std::string> versions;
	values.assign(vals, vals+13);
	versions.assign(vers, vers+4);
	Deck d;
	for (int i = 0; i < 4; i++) {
		for(int j = 0; j < 13; j++) {
			int vSel = rand()%values.size();  //this is problematic!!
			Card c(values[vSel], versions[i]);
			values.erase(values.begin()+vSel);
			d.push_back(c);
		}
	}
	return d;
}


The program compiles but crashes immediately. My IDE tells me that the line marked above is the culprit, which doesn't really make sense to me. Any clues?
Awesome, thanks everyone!
I'd also recommend using a struct to define a card. It'll be a lot easier to maintain the deck and it'll be more object oriented since you would normally think of each card as being one "thing".

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Make one instance for each card
struct card
{
   string value;
   string suit;
};

// use c-array or some container type like std::vector or std::deque
const int NUMCARDS(52);
card theDeck[NUMCARDS];
// I'm sure that you can figure out how to insert all 52 cards now.

// to shuffle
std::random_shuffle(theDeck, theDeck + NUMCARDS);
Topic archived. No new replies allowed.