#include <iostream>
#include <time.h>
#include<windows.h>
using namespace std;
int main ()
{
srand(time(NULL));
int arr[]={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,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75};
char ans;
int i,j;
int elem;
int Maxsize = 75;
cout<<"Press y to generate number"<<"\n";
cin >> ans;
one way to do it is to just std::swap() the value you have consumed with the end of the array and decrease the array's logical (kept track of) size by 1 each time.
say you got 42.
your array becomes
1,2,...40,41,75,43,... 74,42
and its size goes from 75 to 74.
next iteration, you pick rand()%74 and do the same thing.
another way to do it, more efficient, is to shuffle (<algorithm> https://www.cplusplus.com/reference/algorithm/shuffle/) the array and just iterate it.
so 1,2,3,4,5 could become
3,2,5,1,4 or whatever.
then first iteration, take [0], next, take[1], ...
both approaches work. The second again is much more efficient, getting rid of all the rand calls and extra nonsense and just tapping a value from a container. If you use a vector you can pop off the back until its empty, same idea.
consider: <random> instead of rand (from C), and <ctime> instead of time.h.
#include <iostream>
#include <random>
#include <numeric> // std::iota
#include <vector>
#include <cctype> // ::tolower
int main()
{
// set size, no magic numbers
constint SIZE { 75 };
// create a C++ pseudo-random engine, seeded with
// C++ true non-deterministic random device
std::default_random_engine prng(std::random_device {}());
// create a vector of SIZE elements
std::vector<int> vec(SIZE);
// fill the vector 1 - SIZE
std::iota(vec.begin(), vec.end(), 1);
// shuffle the vector to have truly random element placement
// using the random engine instance
std::shuffle(vec.begin(), vec.end(), prng);
char yes_no { };
std::cout << "\tThe vector has " << vec.size() << " elements.\n\n";
while (std::cout << "Generate a random number? (y/n) ", // display message
std::cin >> yes_no, // get input
'n' != ::tolower(yes_no)) // compare lower cased input
{
// take the first element from the shuffled vector
std::cout << "The generated number is " << vec[0] << "\n\n";
// erase the first element
vec.erase(vec.begin());
}
std::cout << "\n\tThe vector has " << vec.size() << " elements.\n";
}
The vector has 75 elements.
Generate a random number? (y/n) y
The generated number is 15
Generate a random number? (y/n) Y
The generated number is 70
Generate a random number? (y/n) y
The generated number is 14
Generate a random number? (y/n) y
The generated number is 19
Generate a random number? (y/n) N
The vector has 71 elements.
Repeatedly erasing individual elements from the front of a vector can cause performance issues as the vector updates the memory usage. Erasing from the back of a vector will still have potential performance issues, they should be less severe than from front erasures.
C++ has iterators (think pointers) that can point to the last element of the container:
#include <iostream>
#include <random>
#include <numeric> // std::iota
#include <vector>
#include <cctype> // ::tolower
int main()
{
// set size, no magic numbers
constint SIZE { 75 };
// create a C++ pseudo-random engine, seeded with
// C++ true non-deterministic random device
std::default_random_engine prng(std::random_device {}());
// create a vector of SIZE elements
std::vector<int> vec(SIZE);
// fill the vector 1 - SIZE
std::iota(vec.begin(), vec.end(), 1);
// shuffle the vector to have truly random element placement
// using the random engine instance
std::shuffle(vec.begin(), vec.end(), prng);
char yes_no { };
std::cout << "\tThe vector has " << vec.size() << " elements.\n\n";
while (std::cout << "Generate a random number? (y/n) ", // display message
std::cin >> yes_no, // get input
'n' != ::tolower(yes_no)) // compare lower cased input
{
// take the last element from the shuffled vector
std::cout << "The generated number is " << *(vec.crbegin()) << "\n\n";
// erase the last element
vec.pop_back();
}
std::cout << "\n\tThe vector has " << vec.size() << " elements.\n";
}
No, there is no need to remove any of the elements, from the front or back. The OP was trying to delete elements from the array so I did it with a vector using the container's deletion methods.
In actuality a pointer to the current element that gets updated is a better way to go.
Or use an indexing variable, such as size_t index { };.
Either method can be used in some code logic the container has reached the last element, either from the front or back.
Using an indexing variable would work with the OP's original design of using a regular array, PLUS being able to bail if the user wants more than SIZE random numbers.
#include <iostream>
#include <random>
#include <numeric> // std::iota
#include <array> // std::begin, std::end, std::size
#include <cctype> // ::tolower
int main()
{
// set size, no magic numbers
constexpr size_t SIZE { 75 };
// create a C++ pseudo-random engine, seeded with
// C++ true non-deterministic random device
std::default_random_engine prng(std::random_device {}());
// create a array of SIZE elements
int arr[SIZE];
// fill the array 1 - SIZE
std::iota(std::begin(arr), std::end(arr), 1);
// shuffle the array to have truly random element placement
// using the random engine instance
std::shuffle(std::begin(arr), std::end(arr), prng);
char yes_no { };
std::cout << "\tThe array has " << std::size(arr) << " elements.\n\n";
size_t index { };
while (std::cout << "Generate a random number? (y/n) ", // display message
std::cin >> yes_no, // get input
'n' != ::tolower(yes_no)) // compare lower cased input
{
// has the user already picked all SIZE random numbers?
if (SIZE == index)
{
std::cout << "\nThere are no more available random numbers!\n";
return 0;
}
// take the last element from the shuffled array
std::cout << "The generated number is " << arr[index] << "\n\n";
// increment the index to the next available element
index++;
}
std::cout << "\n\tThe array has " << std::size(arr) - index << " elements.\n";
}