C Generate random numbers without repetition [duplicate] - c

This question already has answers here:
Generating list of random numbers without duplication using C?
(5 answers)
Closed 8 years ago.
I want to generate random numbers between 1 and 13 without repetition
I used this method, but it doesn't make sure there is no reputation.
for ( i = 0; i < 13; i++)
{
array[i] = 1 + (rand() % 13);
}
Please help me.
C language

As a comment said, Fill an array with numbers 1 through 13 then shuffle the array.
int array[13];
for (int i = 0; i < 13; i++) { // fill array
array[i] = i;
printf("%d,", array[i]);
}
printf("\n done with population \n");
printf("here is the final array\n");
for (int i = 0; i < 13; i++) { // shuffle array
int temp = array[i];
int randomIndex = rand() % 13;
array[i] = array[randomIndex];
array[randomIndex] = temp;
}
for (int i = 0; i < 13; i++) { // print array
printf("%d,",array[i]);
}
Here is the sample output.
0,1,2,3,4,5,6,7,8,9,10,11,12,
done with population
here is the final array
11,4,5,6,10,8,7,1,0,9,2,12,3,
Note: I used the most basic sort I could. Use a better one if you want.

Related

Need opinions to optimize my code for sorting and find minimum number of K occurences [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 5 months ago.
Improve this question
int temp = 0;
int counter;
int match = 0;
int FindDup(int array[], int K, int N)
{
// Sorting the array from small big numbers.
for (int i = 0; i < N; i++)
{
for (int j = i + 1; j < N; j++)
{
if (array[i] > array[j])
{
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
// Find minimum number of K occurences
for (int i = 0; i < N; i++)
{
counter = 0;
for (int j = 0; j < N; j++)
{
if (array[i] == array[j]) // checks if array element is equal
{
counter++;
}
}
if (counter == K)
{
match = array[i];
return match;
}
}
return -1;
}
Info about this function:
This function is a mix of sorting and finding minimum occurrences of an array.
Problem:
The function does work as intended but needs optimization from another user for further improvements of the code. It would be great seeing someones opinions of what would be better and what could be changed.
Input:
arraySize: 10
arrayElements: 2 4 6 7 3 4 5 6 3 6
numberOfOccurrences: 2
Output:
3
since the input is just integer array and there is ain't no difference between saying there is 2 and another 2 as they all the same , you could go up with a hashing techniques , there is a lot of hashing techniques out there , just for a little demonstration , assume that the range of the numbers entered is so small , like from 0 -> 45 and all is positive , then you can use hashing . but if there is negative numbers then you have to use other techniques , if the array is like 0 1 2 5 3000 then this will create array of size 3001 if you used direct hashing techniques , but to solve this problem , there is other hashing techniques that could help you.
for example , you could do something like this :
#include <stdio.h>
#include <stdlib.h>
int main() {
int arr[8] = {1, 10, 5, 5, 10, 4, 8, 11};
int max = arr[0];
/*get the maximum element in the array*/
for(int i = 1; i < 8; i++)
{
if(arr[i] > max)
max = arr[i];
}
/*create another variable of size = (max of arr) + 1 and initialized with zeros*/
int *hashTable = (int*) calloc((max + 1), sizeof(int));
/*hashing all the elements*/
for (int i = 0; i < 8; ++i) {
hashTable[arr[i]]++;
}
/*printing the sorted array*/
for (int i = 0; i < (max+1);) {
if(hashTable[i] > 0)
{
printf("%d\t", i);
hashTable[i]--;
}
else
{
i++;
}
}
return 0;
}
and this is the output:
1 4 5 5 8 10 10 11
here , using hashing , you can know the number of occurrence of each element and sort the array in time complexity O(N) .
so simply , read about hashing techniques . that could help answering your question

How can we replace the higest 5 numbers in an array of 10 with 1 and smallest 5 into 0 in C programing?

Here's the question my teacher gave me
Write a C program to store 10 integers in an array of size 10 and
display the contents of the array. Replace the highest 5 numbers in the array by
1 and lowest 5 numbers by 0 and display the contents of the new array.
[For e.g.
Original Array
44 11 6 99 30 78 32 31 66 55
New Array
1 0 0 1 0 1 0 0 1 1
I have been struggling in this question whole day :(
There are a lot of ways to solve this problem. A good way would be sort the array into another array and then replace the 1st half with 0s and the second half with 1s like this:
#include<stdio.h>
int main(){
const int arraySize = 10;
int i, j;
int arr[arraySize];
int arrSorted[arraySize];
int temp;
// Get input from user
printf("Please enter 10 numbers!\n");
for (i = 0; i < arraySize; i++)
{
scanf("%d", &arr[i]);
// Copy array into another to sort it later
arrSorted[i] = arr[i];
}
// Print input
printf("Input: ");
for (i = 0; i < arraySize; i++)
{
printf("%3d ", arr[i]);
}
printf("\n");
//Sort the array in ascending order
for (i = 0; i < arraySize; i++)
{
for (j = i + 1; j < arraySize; j++)
{
if(arrSorted[i] > arrSorted[j])
{
temp = arrSorted[i];
arrSorted[i] = arrSorted[j];
arrSorted[j] = temp;
}
}
}
// Start replacing procedure
for (i = 0; i < arraySize; i++)
{
for (j = 0; j < arraySize; j++)
{
if (arr[j] == arrSorted[i])
{
if (i < arraySize / 2) // Replace 1st half with 0s
{
arr[j] = 0;
}
else // Replace 2nd half with 1s
{
arr[j] = 1;
}
break;
}
}
}
// Print result
printf("Result: ");
for (i = 0; i < arraySize; i++)
{
printf("%3d ", arr[i]);
}
printf("\n");
return 0;
}
Of course, you can use the C standard library qsort() function if you don't want to sort yourself.
Another solution would be, find the median number of the array then replace any number which is less than it with 0 and any number bigger than it with 1. Although with this solution there will be some challenges regarding what to do with the median number itself and what if there are multiple median numbers (duplicated)?

Reverse an integer array in C [duplicate]

This question already has answers here:
Reverse an array in c
(3 answers)
Closed 5 years ago.
Given an integer array with 5 elements [1,2,3,4,5], I am attempting to reverse the order of the elements in the array; e.g. the array would become [5,4,3,2,1].
int main(void) {
int n = 5; //Num of elements
int arr[5] = {1,2,3,4,5};
for (int i = 0; i < n; i++) {
printf("%d\n", arr[i]); //Print original vals
}
n--; //Decrement n by 1 for simplicity
for (int i = n; i >= 0; i--) {
int temp = arr[n - i]; //Set temp the max-index (4) - i
printf("\nSmall: %d\nBig: %d\n", arr[n - i], arr[i]); //Print current temp & arr[i]
arr[n - i] = arr[i]; //Set arr[max-index - i] to arr[i] (e.g arr[0] = arr[4])
arr[i] = temp; //Set arr[i] to arr[max-index - 1] (e.g. arr[4] = arr[0])
printf("\nBig: %d\nSmall: %d\n", arr[n - i], arr[i]); //Print new set
}
for (int i = 0; i < n + 1; i++) { //Print array in reverse order
printf("%d\n", arr[i]);
}
return 0;
}
The first for loop should print:1 2 3 4 5
and the last: 5 4 3 2 1
However, it prints 1 2 3 4 5 both times, but the print statements in the loop that reverses the array prints the right numbers.
Have I done something wrong?
Should I be dynamically allocating memory or something else not allowing me to change the array?
The problem is, you swap every element twice (unless it is the center one) which ultimately does not swap anything. At the first loop, you technically swap first and last item. At the last loop, you did the same. So, you reverse the first action, returning the item back to original position.
Another problem is you try to access arr[5] which is undefined as your array is of size 5 and thus the index should be from 0 to 4 only.
Following is a function reversing the array:
void ReverseArray(int arr[], int size)
{
for (int i = 0; i < size/2; i++)
{
int temp = arr[i];
arr[i] = arr[size - 1 - i];
arr[size - 1 - i] = temp;
}
}
To reverse an array you have to do as follows:
for(int i = i; i<n/2; ++i)
{
int temp = arr[i];
arr[i] = arr[n-i-1];
arr[n-i-1] = temp;
}
You are reversing the array twice.
On each iteration you swap two numbers to the same distance from the center.
So, on the first half of the iterations you have already reversed the array. As you keep iterating you swap again and the array stays unmodified.
To fix it just change the reversing loop to this (change i>=n for i>=n/2 )
for (int i = n; i >= n/2; i--) {...swaping operations...}

Why am I getting duplicates in my array?

So I am making an array of 52 ints, I add in random numbers and make sure there all different. If there is a duplicate I would generate a new number so that current index that am at is different. Where am I going wrong?
for(i=0; i < SIZE; i++){
deck[i] = (rand() % 52);
for(c= 0; c <= i; c++ ){
if(deck[c] == deck[i+1]){
deck[i] = (rand() % 52);
}
}
}
You can't try merely once for the random number in your inner for loop. After you generate it, you have to check all the previously generated items again to make sure you didn't generate the same random number as another item. This would do the trick (assuming SIZE = 52):
for(i=0; i < SIZE; i++){
deck[i] = (rand() % SIZE);
for(c= 0; c < i; c++ ){
if(deck[c] == deck[i]){
// Try another number
i--;
break;
}
}
}
That said, it's not a very fast solution (it could potentially never end). It's better to create an array of numbers 0 to 51 and then shuffle them by swapping two elements at a time. I'm not going to write that for you, but it's a standard way of doing it.
Totally the wrong approach. You don't want random numbers; you want precisely the numbers 0 to 51, in random order. To do this, fill the array with the values 0..51, and then shuffle it properly:
for (int i = 0; i < 52; i += 1) deck[i] = i;
for (int i = 52; i > 1; i -= 1) {
int j = rand() % i;
int temp = deck[j];
deck[j] = deck[i-1];
deck[i-1] = temp;
}

Optimise a code of random number with no repetition in C

I do a code that will display to the screen 10 random numbers with no repetitions. I want to know if we can optimize the code or if you have a better and simple way in order to do this request.
Thanks !!
int main(){
int nbr = 0; srand(time(NULL));
int arr[10], i, j, flag;
for (i = 0; i < 10; i++)
{
do
{
nbr = rand() % 10 + 1;
flag = 1;
for (j = 0; j < i; j ++)
{
if (nbr == arr[j])
{
flag = 0;
break;
}
}
} while (!flag);
arr[i] = nbr;
}
for (i = 0; i < 10; i++)
{
printf("%5d", arr[i]);
}
system("PAUSE");
return 0;
}
So if i get what you're trying to do here it is:
generate an array of numbers between 1 and 10, in a random order (given rand() % 10 + 1)
instead of trial and error I'd suggest the following algorithm:
fill arr with 1...10
shuffle arr
this will run a lot faster
While I agree with the solution provided by Work of Artiz, this will result in the hard question to answer of when to stop shuffling.
To solve this you can use the following solution (which will use more memory, but less clock time):
1 Create an array temp having values 1..10 (ordered, not random)
2 Keep track of the length length of the array (10)
3 Generate a random index rand_i between 0 and length - 1
4 Copy temp[rand_i] to next position in your final array
5 Overwrite temp[rand_i] by temp[length-1]
6 Decrement length
7 Iterate Steps 3 - 6 until your array is filled (10 times)
This will both eliminate your excessive looping, and the problem of when to stop shuffling your array
EDIT: including code
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int main(){
int nbr = 0; srand(time(NULL));
int arr[10], i, j, flag;
int temp[10] = {1,2,3,4,5,6,7,8,9,10};
int length = 10;
for (i = 0; i < 10; i++)
{
nbr = rand() % length; // Generate random index between 0 and length - 1
arr[i] = temp[nbr]; // Copy value from random index in temp to next index in arr
// Now since temp[nbr] is already taken (copied to arr) we should replace it by last available value in temp (temp[lenght])
// and in the next iteration we will create a value between 0 and length -1. This will keep values not yet taken from temp in
// contiguous order
temp[nbr] = temp[length-1];
length--;
}
for (i = 0; i < 10; i++)
{
printf("%5d", arr[i]);
}
return 0;
}

Resources