This webpage gives a perfect solution to generate K random numbers from given N size array: http://www.geeksforgeeks.org/reservoir-sampling/
However, there are a varieties of related questions.
1: implement an algorithm that takes as input an array of distinct element and a size, return a subset of the given size of the array elements. All subset should be equally likely. Return the result in input array itself.
int randomGenerator(int left, int right) {
srand(time(NULL));
return left + rand() % (right - left + 1);
}
// given a size of array and input k, return k subset random numbers.
void randomK(vector<int>& nums, int k) {
default_random_engine seed((random_device())());
for(int i = 0; i < k; ++i) {
swap(nums[i], nums[uniform_int_distribution<int>{i, static_cast<int>(nums.size()) - 1}(seed)]);
}
return;
}
int main(void) {
vector<int> nums{0, 1, 2, 3, 4, 5, 6};
randomK(nums, 3);
for(int i = 0; i < 3; ++i) {
cout << nums[i] << " ";
}
cout << endl;
}
1: The first though is to count the maximum values numbers, generate a random number for this count, traverse the array again and return the random index.
2: we can make use of the reservoir sampling.
#include "header.h"
using namespace std;
// in an unsorted array, there are many maximum values, randomly return one index.
int randomMaximumValueIndex(vector<int>& nums) {
srand(time(NULL));
int maxValue = 0;
int count = 0;
int res = 0;
for(int i = 0; i < nums.size(); ++i) {
if(nums[i] > maxValue) {
maxValue = nums[i];
count++;
res = i;
} else if(nums[i] == maxValue){
if(rand() % ++count == 0) res = i; // if found the other maxValue, randomly update the index.
}
}
return res;
}
int main(void) {
vector<int> nums{0, 1, 6, 3, 6, 5, 6};
cout << randomMaximumValueIndex(nums) << endl;
}