random_shuffle() not working? what am I doing wrong?

Hi, I am new to this forum, and to C++ in general (would say I'm intermediate level on Java). Anyway, am keen to learn more about this powerful language.
Could somebody tell me what I'm doing wrong here, I'm trying to shuffle my vector string elements randomly and then display them but every time I run it it gives me the same output: 5, 3, 2, 1, 6, 4, even though I'm seeding the generator with the time. To confirm srand is working I called rand() various times [not shown in code below] and each time it did work, suggesting the random_shuffle was the one not working.

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
#include <iostream>
#include <string>
#include <vector>
#include <ctime>

using namespace std;

void display(vector<string>);

int main()
{
    vector<string> list;
    list.push_back("1");
    list.push_back("2");
    list.push_back("3");
    list.push_back("4");
    list.push_back("5");
    list.push_back("6");
    
    srand(static_cast<uint>(time(0)));
    random_shuffle(list.begin(), list.end());
    display(list);
}

void display(vector<string> vec)
{
    vector<string>::const_iterator iter;
    for(iter=vec.begin(); iter<vec.end(); iter++)
        cout << *iter << ", ";
    cout << endl;
}
Last edited on
Try this :
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
#include <iostream>
#include <string>
#include <vector>
#include <ctime>
#include <random>
#include <algorithm>

using namespace std;

void display(vector<string>);

int main()
{
  vector<string> list;
  list.push_back("1");
  list.push_back("2");
  list.push_back("3");
  list.push_back("4");
  list.push_back("5");
  list.push_back("6");

  std::random_device rd;
  std::mt19937 g(rd());

  std::shuffle(list.begin(), list.end(), g);
  display(list);
}

void display(vector<string> vec)
{
  vector<string>::const_iterator iter;
  for (iter = vec.begin(); iter<vec.end(); iter++)
    cout << *iter << ", ";
  cout << endl;
}
After adding #include <algorithm> the code works for me and produces a different order each time (assuming I don't run the program twice within the same second).

std::random_shuffle is not guaranteed to use std::rand internally, so it is possible that your implementation requires some other way of seeding it, but I have never heard of it so I think it's more likely that you've made a mistake. Are you sure that you ran the exact code that you have posted here?

Note that std::random_shuffle was deprecated in C++14 and removed in C++17. The new recommendation is to use std::shuffle (not std::random_shuffle) together with one of the standard random generators (e.g. std::mt19937). http://en.cppreference.com/w/cpp/numeric/random
Last edited on
@Thomas - I ran your code and it works and generates different sequence each time. Will have to have a look at the docs to understand it though, not heard of
1
2
 std::random_device rd;
 std::mt19937 g(rd());


@Peter - You c/p'd my exact code with the only addition of #include <algorithm> and it worked and generated different sequence each time? Weird... I tried that and it still doesn't work. No, I didn't run it in the same second or within the same loop or anything like that. Thanks for the suggestions, I'll have a look at that, not familiar with the api at all really (literally started learning c++ a week ago). I do find the documentation a little confusing to follow tbh... Is cppreference the goto site for c++ docs? This site as well as devdocs.io often come up on search engining c++ queries

Thanks for help guys :)
closed account (E0p9LyTq)
Will have to have a look at the docs to understand it

Start here:
http://www.cplusplus.com/reference/random/

and here
http://en.cppreference.com/w/cpp/numeric/random

Lots of simple examples to learn from.
Thanks FurryGuy, will have a butchers!
You c/p'd my exact code with the only addition of #include <algorithm> and it worked and generated different sequence each time?

Yes, I did.

Is cppreference the goto site for c++ docs?

Yes, it seems to be the best one out there. This site (cplusplus.com) is also pretty good (and perhaps a bit easier for beginners to understand?).

These sites are great for looking things up when you know what you're looking for, but if you are just starting to learn about something you can often find more digestible sources elsewhere to get you started. At least that's my experience.
closed account (E0p9LyTq)
Is cppreference the goto site for c++ docs?

cppreference was created to be an online and more convenient version of the C and C++ standards.

It is primarily for experienced programmers, it is not a site that someone can learn C++ without prior experience. It is a reference, not a tutorial.

The cplusplus reference section, while good, is very outdated. No C++14/17/20 changes.

If you were to look at the std::random_shuffle page here you would never know it was deprecated in C++14 and removed entirely from C++17's <algorithm> header.

Initializer lists can be useful for cleaner, more compact code when the elements of a container are already available at creation. Your lines 12-20 could be rewritten as:

std::vector<std::string> list = { "1", "2", "3", "4", "5", "6" };

Range-based for loops can be helpful when accessing a container's elements. Your display() function could be rewritten as:

20
21
22
23
24
25
26
27
void display(std::vector<std::string> vec)
{
   for (auto iter : vec)
   {
      std::cout << iter << ", ";
   }
   std::cout << '\n';
}

A range-based for loop will never access elements that are out of bounds. A very big plus IMO for using them.

http://en.cppreference.com/w/cpp/language/range-for
Last edited on
Topic archived. No new replies allowed.