0

As I mentioned on the title; I have a vector which stores a bunch of words(around 2000 words) and in a part of the project it's expected from me that take a random word from that vector and display it. (the project is word finding-like) I have two classes that one of is main, and other is for taking word from vector. I attached the codes below. Something must have escaped my notice, but I can't get what it is somehow.

#include <iostream>
#include <vector>//must be
#include <string>//must be
#include "Dictionary.h"
#include <set>
using namespace std;

int main()                               //main
{
   vector<string> words;
   Dictionary dict(words);
   words = dict.setElements();
   string randomWord = dict.getaRandomWord(words);   //this line is for generate a random word
   cout << randomWord;         

   return 0;
}

class Dictionary                        //dictionary class
{
public:

Dictionary(::vector<string> a) {
    //getWordsFromFile() = a;
}


/*  public :vector<string> getWordsFromFile() {
vector<string> words;
ifstream inFile;
string tmp;
inFile.open("words.txt");
while (!inFile.eof()) {
    inFile >> tmp;
    words.push_back(tmp);
}

return words;


}*/

vector<string> setElements() {
// Declaring Vector of String type 
set<string> wordsSet;
string buffer;
vector<string> wordsVector;
ifstream inFile;
string tmp;
inFile.open("words.txt");

while (!inFile.eof()) {
    inFile >> buffer;
    wordsSet.insert(buffer);
}

for (set<string>::iterator it = wordsSet.begin(); it != wordsSet.end(); ++it) {
    wordsVector.push_back(*it);
}


/*for (int i = 0; i < wordsVector.size(); i++) {
    cout << wordsVector.at(i)<<endl;            //its for displaying the elements of the vector
}*/

return wordsVector;


}

string getaRandomWord(vector<string> a) {           //function that has supposed to be generate a random word
    
    vector<string> currentVector = a;
    string randomWord;
    int randomNumber = rand() % currentVector.size();
    randomWord = currentVector.at(randomNumber);
    return randomWord;
}
};

takes aging ever

takes aging everytime

EDIT: I placed the seed inside the constructor but leaved other code untouched.So, only changing I made is adding a line of srand(time(nullptr)); inside the Dictionary cons.

class Dictionary
{
public:
Dictionary(::vector<string> a) {
    //getWordsFromFile() = a;
    srand(time(nullptr));
     .
     .
     .
}

And the output was like thumb-trash-truly... There is still an alphabetical order.

  • 1
    You need to seed a random number generator before you start using it, otherwise it will always generate the same sequence. – Mark Ransom Apr 05 '21 at 16:07
  • [Here](https://en.cppreference.com/w/cpp/numeric/random/rand) is an example of seeding rand with the current time. – lakeweb Apr 05 '21 at 16:11
  • Do you mean that I should have created a new function that generates a random number? If so, why this code (int randomNumber = rand() % currentVector.size();) doesn't work for generate a number? Isn't it supposed to generate a different number at every turn? – Mithat Akbulut Apr 05 '21 at 16:13
  • Is it just for c++ or something? I am new at c++, I just knew java before c++ but there was n't such a situation. – Mithat Akbulut Apr 05 '21 at 16:15
  • That's how PRNGs work. Other languages might do it for you. I also fail to see why you bother copying the vector in the function. – sweenish Apr 05 '21 at 16:17
  • Also make sure to seed 1 time only and not every time. A good place to seed is the start of your `int main()` – drescherjm Apr 05 '21 at 16:21
  • I was like "this language expects me that I have to do everything with my hand". I didn't know how seed a generator. while there is already a rand() function, why should I search about this – Mithat Akbulut Apr 05 '21 at 16:24
  • @drescherjm I have to generate a new word inside the dictionary class. Should I still place the seed the start of int main? – Mithat Akbulut Apr 05 '21 at 16:27
  • All of this is before getting into why you should probably avoid `rand()` altogether in C++. – sweenish Apr 05 '21 at 16:33
  • This is an excellent example of why designs that rely on hidden global variables are bad. – Stephen M. Webb Apr 05 '21 at 16:45
  • Guys thanks to you all. It worked a bit. I mean, I placed the seed into the Dictionary container to see what will happen. I just got rid of the "aging" and different words has been generated everytime but it seems like there is still a order between this words. So, the generated words are like: havoc- heavy- hovel.... Do you see the connection between those? They are generated in a alphabetical order as a certain gap between them. Why this is occured? – Mithat Akbulut Apr 05 '21 at 16:48
  • @StephenM.Webb I'm that beginner to couldn't get what it is though – Mithat Akbulut Apr 05 '21 at 16:52
  • ***Should I still place the seed the start of int main?*** Most likely. One reason is if you seed more that 1 time in the same second you are likely to get the same exact "random" number back. Because you would have the same seed. The resolution of time(NULL) is a second/ – drescherjm Apr 05 '21 at 16:54
  • I was referring to the design of rand() from the C standard library: it relies on the state of secret hidden global variables to work and is badly designed. The random number generation in the C++ standard library has a much better design. – Stephen M. Webb Apr 05 '21 at 16:56
  • @drescherjm I tried that already. Didn't work neither into the constructor nor starting of int main. – Mithat Akbulut Apr 05 '21 at 16:57
  • What exactly did you use as a seed? – drescherjm Apr 05 '21 at 17:02
  • @StephenM.Webb Oh I get it. I don't know why they don't combine these two functions(rand and srand) while the other languages have 1 function to generate a random number.(maybe the others are also the same with c++, at least java wasn't like that) – Mithat Akbulut Apr 05 '21 at 17:05
  • In 2011 the rand() / srand() were replaced in the c++ language with better implementations in the – drescherjm Apr 05 '21 at 17:06
  • @drescherjm I used srand(time(nullptr)). There was not a lot alternatives instead nullptr – Mithat Akbulut Apr 05 '21 at 17:07
  • I don't have a good reason why it would still not work. We probably would need to see a minimal example that does not use a file and produces the same output as you see. – drescherjm Apr 05 '21 at 17:09
  • @drescherjm I've edited the post but it seems it's still not that illustrative. – Mithat Akbulut Apr 05 '21 at 17:17
  • Your code has commented out parts and requires a file that we don't have. Both of these make it difficult to test. You may want to create an example at ideone.com that does not read a file (instead populates the `wordsVector` directly in main() ) and produces the same bug that you see. – drescherjm Apr 05 '21 at 17:18
  • I tried to do that and fill the words vector with several alphabetical ordered words. It really worked this time. How I entegrate this into my project? Actually the same thing has been made. There must be a problem with functions. – Mithat Akbulut Apr 05 '21 at 17:47
  • There must be some other bug in your code that we can't see. This is why I asked you to create code that reproduces the issue. Perhaps your file loading is not working as you expect. Perhaps you are recreating the dictionary in a loop. – drescherjm Apr 05 '21 at 17:57
  • I will review it from beginning to end one more time. Thank you so much :) – Mithat Akbulut Apr 05 '21 at 20:21

1 Answers1

1

In order to get a more random number, you need to give it a value to base random values off of, otherwise it will always give the same value. In order to get different values, you will probably want to seed your random number generator with the time to get a greater distribution. Here is a good explanation of what is going on, or you can check the documentation.
What you want to use is std::srand(std::time(null)); one time at the beginning of the program, generally in the constructor. This gives a different set of pseudorandom numbers that will be generated for every pass of the program.

Hawkeye5450
  • 672
  • 6
  • 18
  • It worked a bit. I mean, I placed the seed into the Dictionary container to see what will happen. I just got rid of the "aging" and different words has been generated everytime but it seems like there is still a order between this words. So, the generated words are like: havoc- heavy- hovel.... Do you see the connection between those? They are generated in a alphabetical order as a certain gap between them. Why this is occured? Thanks to you for your expression by the way! – Mithat Akbulut Apr 05 '21 at 16:46