main.cpp
// lottery card game
#include<iostream>
#include<vector>
#include<cstdlib> // srand(),rand()
#include<ctime> // time()
#include<algorithm> // random_shuffle()
#include<set>
using std::vector;
using std::cout;
using std::cin;
vector<int> Lotto(int spots, int rand_num);
// functor, handle int, as element in vector is int
template<typename T>
void Show(T& x) { cout << x << " "; }
int main()
{
char ch;
cout << "Would like to do the test? Enter Y/y to start, other keys to quit.\n";
// cin doesn't read '\n'
cin >> ch;
while (tolower(ch)=='y')
{
std::srand((unsigned)std::time(0));// send seeds
cout << "Enter the max spot-num of the lottery card: ";
int spots;
cin >> spots;
cout << "Enter how many cards you want to pick" << " (<= " << spots << " ): ";
int rand_num;
cin >> rand_num;
// vector to store
vector<int> vec;
vec = Lotto(spots, rand_num);
std::for_each(vec.begin(), vec.end(), Show<int>);
// prompt if wanna do again
cout << "\n\nWould like to do again? 'Y/y' to continue,other keys to quit: ";
cin >> ch;
}
cout << "Bye!";
cin.get();
cin.get();
}
// APPROACH 1: use a vector contains "spots" elements
// then use random_shuffle() reorder them, use the beginning of "rand_num" elements
vector<int> Lotto(int spots, int rand_num)
{
// create a vector to store targeted elements, which is in sorted order, selected at random
vector<int> vec(rand_num);
// assing value to vector elements, each element is unique, no duplicate
for (int i = 0; i < rand_num; i++)
{
// generate a random value ranges from 1~spots, then assign to *vec
vec[i] = std::rand() % (spots + 1);
// make vec[i] not negative
while (vec[i] <= 0)
vec[i] = std::rand() % (spots + 1);
// make vec has no duplicate elements
// compare new element with all previous elements, if true,compare start over again
// in case when equal to vec[10],geneate a new value equal to vec[0]~vec[9]
for (int j = 0; j < i; j++)
{
if (vec[i] == vec[j])
{
// if value is same as any one of previous values,get a new value, and compare again
vec[i] = std::rand() % (spots + 1);
continue;
}
}
}
// shuffle the order
std::random_shuffle(vec.begin(), vec.end());
// sort the order
std::sort(vec.begin(), vec.end());
// did not return vec& but a copy of vec, as vec will be released after this function
return vec;
}
/*
// APPROACH 2: use set plays the role of sort() (consume CPU and memory, not good choice,only wanna practise STL containers)
// method 1:vector store 1~spots, copy the beginning of the set to another set
// method 2:vector store rand_num elements generated by rand()
// here use method 1
vector<int> Lotto(int spots, int rand_num)
{
// use vector,as set can't use random_shuffle()
vector<int> vec;
for (int i = 1; i < (spots + 1); i++)
vec.push_back(i);
std::random_shuffle(vec.begin(), vec.end());
// use set's constructor, automatically sort, use sort() instead of set will be prefered
std::set<int> se(vec.begin(), vec.begin() + (rand_num + 1));
// copy and cover original values
std::copy(se.begin(), se.end(), vec.begin());
vec.erase(vec.begin() + (rand_num + 1), vec.end());
// return a copy of vec;
return vec;
}
*/