How to generate random numbers without duplicates using a loop in c++? - 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;
}

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++;
}
}

Related

Adding conditions to a conditional statement

I am messing around with dynamic arrays for a user defined amount of inputs for an and gate.
The issue I am running into is that I don't know how many inputs the user is going to test and I need to be able to have an if-else statement that tests each input.
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
class logic_gate {
public:
int x = 0;
};
int main() {
int userInput = 0;
cout << "How many inputs do you want on your and gate?: ";
cin >> userInput;
cout << endl;
logic_gate *and_gate = new logic_gate[userInput];
cout << endl << "Please enter the values of each bit below . . ." << endl <<
endl;
int userTest1 = 0;
for (int i = 0; i < userInput; i++) {
cout << "#" << i + 1 << ": ";
cin >> userTest1;
and_gate[i].x = userTest1;
}
return 0;
}
Here is the code that I am currently trying to find a solution for.
To implement an AND gate with n inputs you can simply do:
int output = 1;
for (int i = 0; i < n; ++i)
{
if (!and_gate [i])
{
output = 0;
break;
}
}
// ...
Use Vector data structure, you don't need to tell its size while declaring, unlike array, and it can grow automatically.
To read input till it's arriving, put cin inside while loop condition. I used getline to read whole line and work with it, so that whenever user presses enter button at empty line, program will think that no more input is coming anymore, and will start calculating 'And' of inputs.
//don't forget to import vector
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class logic_gate {
public:
int x = 0;
logic_gate(){ //default constructor
}
logic_gate(int k){ //another constructor needed
x = k;
}
};
int main(){
cout << endl << "Please enter the values of each bit below . . ." << endl;
vector<logic_gate> and_gate; //no need to tell size while declaration
string b;
while(getline(cin, b)){ //read whole line from standard input
if (b == "\0") //input is NULL
break;
and_gate.push_back(logic_gate(stoi(b))); //to convert string to integer
}
if (!and_gate.empty()){
int output = and_gate[0].x;
for (int i = 1; i < and_gate.size(); i++){
output = output & and_gate[i].x;
}
cout << "And of inputs is: " << output << endl;
}
else{
cout << "No input was given!\n";
}
return 0;
}
Feel free to ask if some doubts linger
I figured out what I wanted to do. Thanks to everyone who helped and especially Paul Sanders. Below is my final code.
#include <iostream>
using namespace std;
class logic_gate {
public:
int x = 0;
};
int main() {
int userInput;
int output = 1;
cout << "How many inputs do you want on your and gate?: ";
cin >> userInput;
cout << endl;
logic_gate *and_gate = new logic_gate[userInput];
cout << endl << "Please enter the values of each bit below . . ." << endl <<
endl;
int userTest1;
for (int i = 0; i < userInput; i++) {
cout << "#" << i + 1 << ": ";
cin >> userTest1;
and_gate[i].x = userTest1;
}
if (userInput == 1) {
output = userTest1;
cout << "The test of " << userTest1 << " is " << output << endl << endl;
}
else if (userInput > 1) {
for (int i = 0; i < userInput; i++) {
if (!and_gate[i].x)
{
output = 0;
break;
}
}
cout << "The test of ";
for (int i = 0; i < userInput; i++) {
cout << and_gate[i].x;
}
cout << " is " << output << endl << endl;
}
return 0;
}

Duplicate Elimination c++ using unique_copy Algorithm (Exercise 16.9)

I tried to create the duplicate elimination exercise using unique_copy algorithm. I need to enter 20 integers into an empty vector. However, the output said all zeros (0 0 0 ... 0 0 0) in the vector. What should I do so that I can find the unique variables in the vector using unique_copy algorithm? Exercise 16.9 of the textbook (C++ How to Program 9th Edition) says, "Use a back_inserter to enable the vector to grow as new items are added. Use the copy algorithm to display the unique values." (738)
Here is the code:
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <iterator>
using namespace std;
typedef vector<int, allocator<int> > vec_t;
typedef insert_iterator<vec_t> vec_iter;
typedef ostream_iterator<int, char, char_traits<char> > os_iter;
int main()
{
int SIZE = 20;
int twenty[20] = {};
vec_t v20(twenty, twenty + 20);
int entry;
int current_index = 0;
bool duplicated = false;
for(int i = 0; i <= SIZE; i++)
{
cout << "Enter number: " << endl;
cin >> entry;
if(entry > 10 && entry < 100)
{
for(int u = 0; u < current_index; u++)
{
if(twenty[i] == entry)
{
cout << "You already entered these numbers " << endl;
duplicated = true;
break;
}
}
if(duplicated == false)
{
twenty[current_index] = entry;
current_index++;
}
}
else
{
cout << "Error: invalid number; you must enter between 10 and 100 " << endl;
i--;
}
}
for(int x = 0; x < current_index; x++)
{
cout << twenty[x] << endl;
vec_t outcome;
vec_iter ins (outcome, outcome.begin());
cout << "Vector: " << endl << " ";
copy(v20.cbegin(), v20.cend(), os_iter(cout, " "));
cout << endl;
unique_copy(v20.cbegin(), v20.cend(), ins);
cout << endl << "After unique_copy, outcome contains ";
copy(outcome.cbegin(), outcome.cend(), os_iter(cout, " "));
cout << endl;
}
return 0;
}
I hope you will help me solve problems.
ChonglinXu

Converting String to vector of Integers

FizzBuzz program. The user enters numbers separated by a comma. The program reads input and lets the computer know if divisible by 3, 5 or both. When the user enters 15,5,30, the program will only output the first number, 15 and stops there. What am I doing wrong?
void processVector(vector<int> intVector)
{
bool loop;
for (int i = 0; i < intVector.size(); i++)
{
loop = true;
}
}
int main()
{
cout << "Welcome to the FizzBuzz program!" << endl;
cout << "This program will check if the number you enter is divisable by
3, 5, or both." << endl;
cout << "Please enter an array of numbers separated by a comma like so,
5,10,15" << endl;
cin >> userArray;
vector<int> loadVector(string inputString);
istringstream iss(userArray);
vector <int> v;
int i;
while (iss >> i);
{
v.push_back(i);
if (iss.peek() == ',')
iss.ignore();
if (i % 15 == 0)
{
cout << "Number " << i << " - FizzBuzz!" << endl;
}
else if (i % 3 == 0)
{
cout << "Number " << i << " Fizz!" << endl;
}
else if (i % 5 == 0)
{
cout << "Number " << i << " Buzz!" << endl;
}
else
{
cout << "Number entered is not divisable by 3 or 5." << endl;
}
}
system("pause");
}
Here is how I would approach the problem:
#include <iostream>
#include <string>
#include <vector>
int main() {
std::cout << "!!!Hello World!!!" << std::endl; // prints !!!Hello World!!!
std::cout << "Please enter your numbers seperated by a comma (5, 3, 5, 98, 278, 42): ";
std::string userString;
std::getline(std::cin, userString);
std::vector<int> numberV;
size_t j = 0; // beginning of number
for(size_t i = 0; i < userString.size(); i++){
if((userString[i] == ',') || (i == userString.size() -1)){ // could also use strncmp
numberV.push_back(std::stoi(userString.substr(j, i))); // stoi stands for string to int, and .substr(start, end) creates a new string at the start location and ending at the end location
j = i + 1;
}
}
for(size_t n = 0; n < numberV.size(); n++){
std::cout << numberV[n] << std::endl;
}
return(0);
}
This should give you a method to solve the problem (without handling the fizzbuzz part of your program) that I personally find simpler.
The basic form for using functions is:
<return type> <function_name(<inputs)>{
stuff
};
So, a basic function that takes a string and returns a vector (what you are wanting) would be:
std::vector myStringToVector(std::string inputString){
std::vector V;
// your code (see the prior example for one method of doing this)
return(V);
};
It also looks like they want a separate function for outputting your vector values, this could look something like:
void myVectorPrint(std::vector inputVector){
// your code (see prior example for a method of printing out a vector)
};
Thank you #Aaron for the help. Here is the finished code and it works great!
I had to take a little more time researching a few things and trying to understand which order and what to put where in terms of the functions and how to call them. I appreciate all the help as I said I am a noob.
#include "stdafx.h"
#include <iostream>
#include<sstream>
#include<string>
#include<vector>
using namespace std;
vector<int> loadVector(string inputString)
{
stringstream ss(inputString);
vector <int> numberV;
int n;
size_t j = 0; // beginning of number
for (size_t n = 0; n < inputString.size(); n++)
{
if ((inputString[n] == ',') || (n == inputString.size() - 1))
{
numberV.push_back(std::stoi(inputString.substr(j, n)));
j = n + 1;
}
}
return numberV;
}
void processVector(vector<int> intVector)
{
for (int i = 0; i < intVector.size(); i++)
{
int n = intVector.at(i);
if (n % 15 == 0)
{
cout << "Number " << n << " - FizzBuzz!" << endl;
}
else if (n % 3 == 0)
{
cout << "Number " << n << " Fizz!" << endl;
}
else if (n % 5 == 0)
{
cout << "Number " << n << " Buzz!" << endl;
}
else
{
cout << "Number entered is not divisable by 3 or 5." << endl;
}
}
}
int main()
{
cout << "Welcome to the FizzBuzz program." << endl
<< "Please enter an array of numbers separated by comma's (5, 10, 15)"
<< endl;
string inputString;
getline(cin, inputString);
try
{
vector<int> intVector = loadVector(inputString);
processVector(intVector);
}
catch (const exception& e)
{
cout << "Exception caught: '" << e.what() << "'!;" << endl;
}
system("pause");
return 0;
}

Not taking the input

I want to write a program that only takes odd numbers, and if you input 0 it will output the addition and average, without taking any even number values to the average and the addition. I'm stuck with not letting it take the even values..
Heres my code so far:
int num = 0;
int addition = 0;
int numberOfInputs = 0;
cout << "Enter your numbers (only odd numbers), the program will continue asking for numbers until you input 0.." << endl;
for (; ;) {
cin >> num;
numberOfInputs++;
addition = addition + num;
if (num % 2 != 0) {
//my issue is with this part
cout << "ignored" << endl;
}
if (num == 0) {
cout << "Addition: " << addition << endl;
cout << "Average: " << addition / numberOfInputs << endl;
}
}
Solution of your code:
Your code doesn't working because of following reasons:
Issue 1: You adding inputs number without checking whether it's even or not
Issue 2: If would like skip even then your condition should be as follow inside of the loop:
if (num%2==0) {
cout << "ignored:" <<num << endl;
continue;
}
Solving your issues, I have update your program as following :
#include <iostream>
#include <string>
using namespace std;
int main()
{
int num = 0;
int addition = 0;
int numberOfInputs = 0;
cout << "Enter your numbers (only odd numbers), the program will continue asking for numbers until you input 0.." << endl;
for (; ;) {
cin>> num;
if (num%2==0) {
cout << "ignored:" <<num << endl;
continue;
}
numberOfInputs++;
addition = addition + num;
if (num == 0) {
cout << "Addition: " << addition << endl;
cout << "Average: " << addition / numberOfInputs << endl;
break;
}
}
}
#include <iostream>
#include <stdio.h>
using namespace std;
int main() {
int number;
int sum=0;
int average=0;
int inputArray[20]; // will take only 20 inputs at a time
int i,index = 0;
int size;
do{
cout<<"Enter number\n";
cin>>number;
if(number==0){
for(i=0;i<index;i++){
sum = sum + inputArray[i];
}
cout << sum;
average = sum / index;
cout << average;
} else if(number % 2 != 0){
inputArray[index++] = number;
} else
cout<<"skip";
}
while(number!=0);
return 0;
}
You can run and check this code here https://www.codechef.com/ide
by providing custom input

Mastermind string cout issue

Ok I have been struggling with this code and I think I have it written out right but here is the rules from my teacher
1 = implies right Number, Right Place.
2 = implies right Number, Wrong Place.
0 = implies Wrong Number.
So the computer decides on 12345; the user guesses 11235; the computer should respond with 10221. Hint: Watch out for a double number like 11 when there is only one.
I have it where it does all of that except I can not get it to show a 0 when it is wrong can you please help me every single part is written except that part here is my code
// Programming 2
// Mastermind
#include "stdafx.h"
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <string>
using namespace std;
struct fields{//the list of variables used in my program
int size = 5;;
int range = 9;
char lowest = '0';
string guess;
string answer;
int number;
int correct;
int position;
bool gameover = false;
};
void gameplay(fields & info);//declaring the function
int main()
{
fields game;
gameplay(game);//calling the function
system("pause");
return 0;
}
void gameplay(fields & info){//calling the structure into the function
srand(time(0));//to randomize number
info.answer = "";//getting the number
for (int i = 0; i < info.size; i++)
{
char ch = info.lowest + rand() % info.range;
info.answer += ch;
}
info.number = 1;
info.correct = 0;
info.position = 0;
while (!info.gameover)//using a while loop to let them go until they guess it
{
cout << "Guess #" << info.number << ": Enter 5 numbers that are '0' through '9': ";//asking them to guess
cout << info.answer;
cout << "\n";
cin >> info.guess;
if (info.guess == info.answer)//if the guess is right this will end the game
{
cout << "Right! It took you " << info.number << " move";
if (info.number != 1) cout << "s";
cout << "." << endl;
info.gameover = true;
}
int correctNumbers = 0;
for (char const &ch : info.guess) //seeing if there are numebrs in the guess that is in the answer
{
if (info.answer.find(ch) != string::npos)
{
++correctNumbers;
}
}
int const digits = 5;
int correctPositions = 0;
int correctPosition[digits];
int test = 0;
for (int i = 0; i < digits; ++i)//telling which numbers is correct and displaying the 2 or 0 for number is correct or number is wrong
{
if (info.answer[i] == info.guess[i])
{
++correctPositions;
}
if (info.answer[i] == info.guess[i]){
correctPosition[i] = 2;
cout << correctPosition[i];
}
if (correctPosition[i] != 2){
correctPosition[i] = 1;
cout << correctPosition[i];
}
if (correctPosition[i] != 2 && correctPosition[i] != 1)){
correctPosition[i] = 0;
cout << correctPosition[i];
}
}
cout << "\nYou have " << correctPositions << " numbers in the correct position " <<endl;
cout << "You have " << correctNumbers <<" correct numbers in the wrong position"<< endl;
}
cout << "GAME OVER\n\n";
}