Usus woa
Usus woa

Reputation: 43

How to generate random numbers without duplicates using a loop in c++?

I am writing a random name generator without duplicates. I want to do it without other libaries like algorithm because I want to understand how to do that. Is there a way to do that with a loop or a vector?

I thaught of adding the names that have already been to a vector and then check all the elements of the vector with a while loop but I didn't know how I can do that.

    #include <windows.h>
    #include <conio.h>
    #include <vector>
    #include <ctime>
    #include <iostream>
    #include <ctime>
    
using namespace std;

int main() {
 srand((unsigned)time(0));   
    int names = 1;
    int a = 0;
    int x = 0;
    vector <string> vectornames;
    cout << "How many names would you like to add: ";
int amount_of_names;
cin >> amount_of_names;
    while (a < amount_of_names) {

 
cout << "Enter name " << names << ": ";
string name;
cin >> name;
vectornames.push_back(name);
names++;       
a++;   


    
   
       
    }
    while (x < amount_of_names) {
     cout << "\n" << vectornames.at(x);
    x++;   }
    
    cout << "\npress enter to continue: ";
    getch();
    system("cls");
    int z = 0;
while (z < amount_of_names) { 
     
     int random_number = (rand() % amount_of_names);
     if (vectornames.at(random_number) != vectornames.at(z)) {
    cout << "Hello ";
    cout << vectornames.at(z);
    cout << "! You will get " << vectornames.at(random_number) << "\n";
    vectornames.push_back(vectornames.at(random_number));
    
    
    getch();
     
    z++;
}}

    cout << "\n\n";
  

  return 0;
    }

Upvotes: 0

Views: 165

Answers (1)

Surt
Surt

Reputation: 16129

The last part has some problems, you select as many names are you have entered, don't know if that was intended lets just say it was. You add the selected names to the same vector, you don't check correctly for duplicates.

while (z < amount_of_names) {    <-- same amount as was entered in original loop
  int random_number = (rand() % amount_of_names);
  if (vectornames.at(random_number) != vectornames.at(z)) { <--- doesn't check for duplicates
    cout << "Hello ";
    cout << vectornames.at(z);
    cout << "! You will get " << vectornames.at(random_number) << "\n";
    vectornames.push_back(vectornames.at(random_number)); <---- adding to same vector
    getch();
    z++;
  }
}

Lets see what can be done without using algoritmes ... that means we need to implement std::find or use some other structure to keep check on what is already selected.

!!!Warning untested code!!!

bool Find(const std::string& needle, const std::vector<std::string>& haystack) const {
  for(const auto& straw : haystack) {
    if (straw == needle) {
      return true;
    }
  }
  return false;
}

And updated code, which use a different vector to store the used names.

std::vector<std::string> used;

while (z < amount_of_names) {
  int random_number = (rand() % amount_of_names);
  
  if (!Find(vectornames.at(random_number), used)) { 
    cout << "Hello ";
    cout << vectornames.at(z);
    cout << "! You will get " << vectornames.at(random_number) << "\n";
    used.push_back(vectornames.at(random_number));
    getch();
    z++;
  }
}

Upvotes: 1

Related Questions