If I have an array like this
int numbers[10] = {1,1,3,3,5,5,7,7,8,8};
And I want to pick one randomly
i = numbers[rand()% 10];
How could I avoid the pc to pick the same number more than twice for this example. Because like you can see in the array the same number is repeated 2 times. So I would like, for example, the number 8 to be choose just twice and same for the other numbers.
I know that I could do something like mark an element as "deleted", e.g., by setting it to 0, then if the number chosen has been deleted, you choose again. But I don't know how to do it properly, so If anyone here can help me I would be very grateful.
You can generate the random number so it's equal to the yet unused number of elements and move unused elements to the front of the array.
#define SZ 10
int numbers[SZ] = {1,1,3,3,5,5,7,7,8,8};
for (int i = 0; i < SZ; ++i)
{
// Generate the random number in the range [0 .. UNUSED-ELEMENTS]
// First loop in range [0..9]
// Second loop in range [0..8]
// and so on
int r = rand() % (SZ-i);
int d = numbers[r];
printf("%d ", d);
// Overwrite the used element with an unused element, i.e. last unused,
// so that unused elements are always at the lowest array index
numbers[r] = numbers[SZ-i-1];
}
printf("\n");
Implemented with an array + "swap and pop":
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
static int pick_number(int *numbers, int max)
{
int index = rand() % max;
int result = numbers[index];
// Swap
numbers[index] = numbers[max-1];
return result;
}
int main(int argc, char *argv[])
{
srand(time(NULL));
int numbers[10] = {1,1,3,3,5,5,7,7,8,8};
for (int i = 10; i > 0; i--) {
printf("got: %d\n", pick_number(numbers, i));
}
return 0;
}
Related
I am working on an assignment and I'm asked to create an array of fibonacci numbers in a range of 0 to 50,000. Once this array has been initialized I am suppose to create a random number between 2 and 10,000. Then, I'm suppose to compare the members of the fibonacci array with the random number to find the greatest fibonacci number that is less than or equal to the random number.
This is the code that I have so far, it correctly creates the array of fibonacci numbers and the random number. How would I start with comparing the members of the array to the random number?
#include <stdio.h>
#include <string.h>
#include <time.h>
void Get_Fibonacci(int n)
{
int fibArray[25];
int lower = 2, upper = 10000, count = 1;
int i, FibRange = 50000;
int first = 0, second = 1, next = 1;
printf("%d %d", first, second);
//Create fibonacci sequence between 0 and 50,000 and store in array
for (i = 2; (first + second) < FibRange; i++)
{
next = first + second;
fibArray[i] = next;
printf(" %d\n", fibArray[i]);
first = second;
second = next;
}
//Create Random Number between 2 and 10,000
srand(time(0));
int k;
for (k = 0; k < count; k++)
{
n = (rand() % upper - lower + 1) + lower;
}
}
I did a little tweaking to your algorithm. This should do what you are asking.
Basically since the Fibonacci sequence combines of sorted numbers, you can do binary search. Also, in your implementation, your array doesn't have to be of size 25 since you are only holding 23 integers. 0 and 1 are saved in independent variables. In addition, your random number generator was wrong.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX_N 10000
#define MIN_N 2
void Get_Fibonacci()
{
int fibArray[25];
int lower = 2, upper = 10000, count = 1, middle = 0,found=0;
int low=0,high=0;
int i, FibRange = 50000,n;
int first = 0, second = 1;
printf("\n\t Fibonacci sequence:\n");
fibArray[0]=0;
fibArray[1]=1;
printf("%d\n%d\n",fibArray[0],fibArray[1]);
/* Creates a fibonacci sequence between 0 and 50,000 and store in an array */
for (i=2; (first+second)<FibRange; i++)
{
fibArray[i]=first+second;
first=second;
second=fibArray[i];
printf("%d\n",fibArray[i]);
}
high=i-1 /* Using the for loop exit condition, as chux suggested */
/* Generates a random number between 2 and 10,000 */
srand(time(0));
n = rand()%(MAX_N+1-MIN_N)+MIN_N;
/* Binary search algorithm */
while (low<=high&&!found)
{
middle=(low+high)/2;
if (n==fibArray[middle])
{
count=fibArray[middle];
found=1; /* To terminate the loop if we have an exact match */
}
else if (n<fibArray[middle])
{
high=middle-1;
}
else
{
low=middle+1;
count=fibArray[middle]; /* Saving the number less than key value */
}
}
printf("\n\tRandom number was: %d\n",n);
printf("\n\tClosest match was: %d\n",count);
return;
}
int main(void)
{
Get_Fibonacci();
return 0;
}
First, need to claify somethings:
1) the for loop for creating a random number is useless since count is always is one
2) n should not be a parameter for the function since you generate a random number in the function
3) the i should start from 0, starting from 2 doesn't make any sense to me. You’re just wasting the first two elements in the array
Largest is the variable that carries the value of the largest element and still smaller than n.
int Largest = fibArray[0];
for(int counter=1; counter<25; counter++){
if(fibArray[counter]>Largest && fibArray[counter]<n)
Largest = fibArray[counter];
}
return Largest;
Lambda expression makes these sort of things significantly easier. I suggest learning about lambda and delegates to help with problems like this in the future
// What I mean by this is shown by my example:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int i;
int a;
for (a = 0;a <10;a ++) {
i = (rand()%10)+1; // generates a number from 1-10
printf("%d\n", i);
}
// I would like for the loop to generate a number that gives a number that was not generated before. For example, an output such as:
1,3,6,2,8,9,4,10,5,7
instead of:
3,9,10,3,7,9,2,7,10,1
In other words, I would like no copies.
You obviously don't just want no copies, but you want every number in a given set exactly once. This is, as commented by Robert, similar to shuffling a deck of cards. You don't have "decks" in C, but you can model one as an array:
int deck[] = {1,1,1,1,1,1,1,1,1,1};
This should represent 10 different "cards" (identified by their index in the array), each available one time. Now, just write code that "draws" cards:
int i = 0; // starting point for searching for the next card to draw
for (int n = 10; n > 0; --n) // how many cards are left
{
int skip = rand() % n; // randomly skip 0 .. n cards
while (1)
{
if (deck[i]) // card still available?
{
if (!skip) break; // none more to skip -> done
--skip; // else one less to skip
}
if (++i > 9) i = 0; // advance index, wrapping around to 0
}
deck[i] = 0; // draw the card
printf("%d\n", i+1); // and print it out
}
of course, seed the PRNG (e.g. srand(time(0))) first, so you don't get the same sequence every time.
The idea shown in the question is to print numbers within a range, without repetition. Here is one way to do that, by putting each value into an array and swapping its elements around.
A variation could be that you don't want to use all the possible numbers, in that case just change PICKED.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ARRLEN 10
#define PICKED 10
int main(void) {
int array[ARRLEN];
srand((unsigned)time(NULL)); // seed the PRNG
for(int i = 0; i < ARRLEN; i++) { // generate the numbers
array[i] = i + 1;
}
for(int i = 0; i < ARRLEN; i++) { // shuffle the array
int index = rand() % ARRLEN;
int temp = array[i];
array[i] = array[index]; // by randomly swapping
array[index] = temp;
}
for(int i = 0; i < PICKED; i++) { // output the numbers
printf("%d ", array[i]);
}
printf("\n");
}
Program output:
9 8 4 5 1 10 7 3 6 2
The library's PRNG is not very random, but for many cases that is not important. If it is, better algorithms are available.
I'm trying to create a hash table. Here is my code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define N 19
#define c1 3
#define c2 5
#define m 3000
int efort;
int h_table[N];
int h(int k, int i)
{
return (k + i*c1 + i*i*c2) % N;
}
void init()
{
for (int i = 0; i < N; i++)
h_table[i] = -1;
}
void insert(int k)
{
int position, i;
i = 0;
do
{
position = h(k, i);
printf("\n Position %d \n", position);
if (h_table[position] == -1)
{
h_table[position] = k;
printf("Inserted :elem %d at %d \n", h_table[position], position);
break;
}
else
{
i += 1;
}
} while (i != N);
}
void print(int n)
{
printf("\nTable content: \n");
for (int i = 0; i < n; i++)
{
printf("%d ", h_table[i]);
}
}
void test()
{
int a[100];
int b[100];
init();
memset(b, -1, 100);
srand(time(NULL));
for (int i = 0; i < N; i++)
{
a[i] = rand() % (3000 + 1 - 2000) + 2000;
}
for (int i = 0; i < N ; i++)
{
insert(a[i]);
}
print(N);
}
int main()
{
test();
return 0;
}
Hash ("h") function and "insert" function are took from "Introduction to algorithms" book (Cormen).I don't know what is happening with the h function or insert function. Sometimes it fills completely my array, but sometimes it doesn't. That means it doesn't work good. What am I doing wrong?
In short, you are producing repeating values for position often enough to prevent h_table[] from being populated after only N attempts...
The pseudo-random number generator is not guaranteed to produce a set of unique numbers, nor is your h(...) function guaranteed to produce a mutually exclusive set of position values. It is likely that you are generating the same position enough times that you run out of loops before all 19 positions have been generated. The question how many times must h(...) be called on average before you are likely to get the value of an unused position? should be answered. This may help to direct you to the problem.
As an experiment, I increased the looping indexes from N to 100 in all but the h(...) function (so as not to overrun h_table[] ). And as expected the first 5 positions filled immediately. The next one filled after 3 more tries. The next one 10 tries later, and so on, until by the end of 100 tries, there were still some unwritten positions.
On the next run, all table positions were filled.
2 possible solutions:
1) Modify hash to improve probability of unique values.
2) Increase iterations to populate h_table
A good_hash_function() % N may repeat itself in N re-hashes. A good hash looks nearly random in its output even though it is deterministic. So in N tries it might not loop through all the array elements.
After failing to find a free array element after a number of tries, say N/3 tries, recommend a different approach. Just look for the next free element.
I am writing a code which will print 5 unique and random strings from an array of 10 strings. But my code doesn't print it uniquely, there are always some repetitions.
Here is my code, can anyone suggest how to make it print unique?
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
void main(void){
char arr[10][10]={"abc","def","ghi","klm","nop","qrs","tuv","wxy","zab","cde"};
int i=0,j=0;
srand(time(0));
for(i=0;i<5;i++){
j=rand()%10;
printf("%d\n",j);
}
}
Just remember idices that have already been printed out:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
char arr[10][10] = {"abc","def","ghi","klm","nop","qrs","tuv","wxy","zab","cde"};
int i = 0, j = 0;
int done[10] = { 0 };
srand(time(0));
for (i = 0; i < 5; ++i)
{
do
{
j = rand()%10;
}
while (done[j] == 1);
done[j] = 1;
printf("%s\n", arr[j]);
}
return 0;
}
Your rand() function may evaluate to the same string index multiple times. There are different ways to resolve that. Most of them will be a take off on bit vector approach. You can create a Boolean array and initialize it to false. Whenever a number is printed, you can change the element in the Boolean array for that index to true. If an element is selected, you can check in the Boolean array if it has already been printed. If yes, you can regenerate the random number, or move to the next unprinted element, making sure that the corresponding Boolean entry is changed to true when you print that element.
Your random function gives the repetition, e.g. your dice throw '3' two time out of 4 throws.
What you could do to make it simple, create an array [0..9],
and let the random function swap a[i] with a[j].
Then you get a random permutation. Take the first 5 elements of the permutated array.
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include <time.h>
int main(){
char arr[10][10]={"abc","def","ghi","klm","nop","qrs","tuv","wxy","zab","cde"};
int found[10] = { 0 };
int i = 0,j = 0;
srand(time(NULL));
for(i = 0; i < 5; i++){
j = rand() % 10;
while(1){
if(!found[j]) break;
j = rand() % 10;
}
found[j] = 1;
printf("%s\n", arr[j]);
}
return 0;
}
My goal is to produce a program which can take a random number from the user (srand) and then feed it to a random number generator (rand) which then chooses 1000 iterations of a random number between 1 and 10. I then want to output how many of each number was seen (i.e. 7 appears 83 times, etc).
I'm able to printf 1000 numbers between 1 and 10 randomly after taking the initial digit from the user, but can't figure out how to take this output and feed it to an array which can then be used to break down the information for printing. Can anyone please help?
#include <stdio.h>
#include <stdlib.h>
int rand1(void);
void srand1(unsigned int seed);
int main()
{
int rand_array[1000];
int count;
int start=1;
int end=10;
int number_var;
int ones=0;
int twos=0;
int threes=0;
int fours=0;
int fives=0;
int sixes=0;
int sevens=0;
int eights=0;
int nines=0;
int tens=0;
int frequency[11];
int i=0;
unsigned seed;
printf("Please enter your choice for seed.\n");
printf("(between 1-10)");
while (scanf("%u", &seed) == 1)
{
srand1(seed);
for(i=0; i < 1000; i++)
{
rand_array[i]=rand1()%(end-start+1)+start;
frequency[rand_array[i]]++;
}
for(i = 1; i < 11; i++)
{
printf("There are %d %d's\n", frequency[i], i);
}
}
return 0;
}
int rand1(void)
{
static unsigned long int next = 1;
next = next * 1103515245 + 12345;
return (unsigned int) (next/65536) % 32768;
}
void srand1(unsigned int seed)
{
static unsigned long int next = 1;
next = seed;
}
You could have an array of size 10 (or 11), type integer, where each slot represents the number of times that number is generated. For example, slot 3 would represent the number of times you generated a 3. So try this:
//declare array to hold frequencies
int frequency[11];
//reset all slots to 0
for(int i = 1; i < 11; i++)
{
frequency[i] = 0;
}
//for each random number, increment the associated slot in the frequency array
for(int i = 0; i < 1000; i++)
{
frequency[rand_array[i]]++;
}
//print the results
for(int i = 1; i < 11; i++)
{
printf("There are %d %d's\n", frequency[i], i);
}
Note: I did not really read through most of your existing code, so I'm not sure if you have any other issues.
Edit: Here is an example of the general idea.
Say you have some random numbers:
5, 2, 4, 9, 9, 2, 1, 10
Your frequency array starts at 0s:
[0,0,0,0,0,0,0,0,0,0]
So now we loop over your random numbers, and increment the associated slot.
For example, we read the 5, now our frequency array is:
[0,0,0,0,1,0,0,0,0,0]
Then the 2:
[0,1,0,0,1,0,0,0,0,0]
Then the 4:
[0,1,0,1,1,0,0,0,0,0]
Then the 9:
[0,1,0,1,1,0,0,0,1,0]
Again
[0,1,0,1,1,0,0,0,2,0]
At the end:
[1,2,0,1,1,0,0,0,2,1]
Now we know how many of each number there are! Say we want to know how many 9's there were, we just look at the 9th slot and we see that there were 2 of them.
Does this make more sense? This is much better than having 10 separate variables for each number, and then saying "if the number was a 1, increment my 1s variable, if it was a 2, increment the 2s variable". Plus if you have, say, random numbers between 1 and 100 instead of 1-10, it will be much easier to adapt your code.