Sorting an array of unique random numbers at insertion - arrays

I found a piece of code that works well to fill an array with a unique random numbers.
My problem now is, that I want to sort these numbers, but not after the array is full but
as new numbers are being inserted. So as each new number is inserted into the array, if finds the position it is meant to be in. The code I have for creating unique random numbers is below, thank you in advance:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
#define MAX 2000 // Values will be in the range (1 .. MAX)
static int seen[MAX]; // These are automatically initialised to zero
// by the compiler because they are static.
static int randomNum[1000];
int main (void) {
int i;
srand(time(NULL)); // Seed the random number generator.
for (i=0; i<1000; i++)
{
int r;
do
{
r = rand() / (RAND_MAX / MAX + 1);
}
while (seen[r]);
seen[r] = 1;
randomNum[i] = r + 1;
}
for (i=0; i<1000; i++)
cout << randomNum[i] << endl;
return 0;
}

You're looking for insertion sort.
Once you got that working, you should switch to binary insertion sort. Binary insertion sort is much faster if the array is big.

Related

Random-filled vector always returns the same numbers

I am completely new in C and try to fill a vector with random integers and output it afterwards. However, it seems that the vector is always filled with the same number. What do I need to change to really get random payments? There is no limit, the number should only be within the value range of long. Here's my code:
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <vector>
#include <time.h>
int main()
{
long x = 20;
long y = 12;
std::vector<long> entries;
//initialize simple random number generator using current time
srand(time(NULL));
for (int step = 0; step < x; step++) {
entries.push_back(rand());
++entries[step];
}
for (std::vector<long>::const_iterator i = entries.begin(); i != entries.end(); ++i) {
printf("%ld\n", i);
}
return 0;
}
EDIT:
I want to solve the issue using plain C not c++!
The main problem in your code is in your last loop
for (std::vector<long>::const_iterator i = entries.begin(); i != entries.end(); ++i) {
printf("%ld\n", i);
}
You're not printing a value from the vector, but an iterator that's pointing to it
Change the line inside the loop to printf("%ld\n", *i); to fix it.
Better yet, you can use a range-loop to make it even simplier
for(auto& number : entries){
std::cout<<number<<'\n'; //or printf("%ld\n",number), like in your code
}
If you want your solution to be pure C, you'll need to use arrays instead of vectors.
I'm missing some informations here, but a basic C program that uses srand() and rand() would look like this :
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#define NB_ENTRIES (20)
#define RANDOM_MAX_RANGE (50) // you should update that
// Don't use srand(time(NULL)) because if you start many time this
// program too quickly, you'll have the same values in all instances.
void Randomize(void)
{
struct timeval time;
gettimeofday(&time,NULL);
srand((time.tv_sec * 1000) + (time.tv_usec / 1000));
}
// Returns a value between 0 and toNumber-1
// Thanks to Bathsheba for pointing out an error with my first version.
int RandomInt(int toNumber)
{
return (int)(rand()/(RAND_MAX + 1.0) * toNumber);
}
// This better but slower version of RandomInt() will ensure
// an even distribution of random values if toNumber is
// greater than around three quarter of RAND_MAX
// NOTE : toNumber must be between 0 and RAND_MAX.
int BetterRandomInt(int toNumber)
{
const int randomSize = RAND_MAX / toNumber;
int returnValue;
do
{
returnValue = rand() / randomSize;
}
while (returnValue >= toNumber);
return returnValue;
}
int main(void)
{
int entries[NB_ENTRIES];
int step;
Randomize();
for (step = 0; step < NB_ENTRIES; step++)
{
entries[step] = RandomInt(RANDOM_MAX_RANGE);
// entries[step] = BetterRandomInt(RANDOM_MAX_RANGE);
}
for (step = 0; step < NB_ENTRIES; step++)
{
printf("%d\n", entries[step]);
}
return 0;
}
Note that I'm using a fixed number of entries. You can make your array dynamic by using pointers and malloc(). Just comment if you need that, but I felt it was out of scope of the question.

C How to Keep a Random Variable From Repeating the Same Number

So I'm just learning C and I would like to know how you could prevent a variable randomized with the rand() function from repeating the same number. I have a script which simply randomizes and prints a variable in a for loop 4 times. How could I make it so the variable never gets the same number after each time it uses the rand() function?
#include <stdio.h>
#include <stdlib.h>
int randomInt;
int main()
{
srand(time(0));
for (int i = 0; i < 4; ++i) {
randomInt = rand() % 4;
printf("%d\n", randomInt);
}
return 0;
}
On most machines, int is 32 bits. So after 232 iterations, you are sure that you'll get some repetition (and probably much before).
If you restrict yourself to much less loops, consider e.g. keeping an array of previously met random numbers (or some hash table, or some binary tree, or some other container).
For a loop repeated only 4 times, keeping an array of (at most 4-1) previously emitted numbers is quite simple, and efficient enough.
Read also about the pigeonhole principle.
A slightly different approach.
int set[] = {0, 1, 2, 3 } ;
srand(time(0));
shuffle(set,4);
using the shuffle algorithm given in this question
https://stackoverflow.com/a/6127606/9288531
I'm guessing that you are getting the same numbers because your are running your program multiple times within the same second. If time(0) hasn't changed, you will have the same seed and the same random numbers generated. Unless your program runs extremely quickly, I imagine using a seed based on microseconds instead of seconds would work:
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
int randomInt;
int main()
{
struct timeval my_microtimer;
gettimeofday(&t1, NULL);
srand(t1.tv_sec * my_microtimer.tv_usec);
for (int i = 0; i < 4; ++i) {
randomInt = rand() % 4;
printf("%d\n", randomInt);
}
return 0;
}
What you could do is keeping track of each number you already generated.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int hasMyNumberAlreadyBeenGenerated(int number, int generatedNumbers[], int size){
for(int i = 0; i < size + 1; i++){
//If you already generated the number, it should be present somewhere in your array
if(generatedNumbers[i] == number) return 1;
//If you did not, find the first available space in your array, and put the number you generated into that space
if(generatedNumbers[i] == 0){
generatedNumbers[i] = number;
break; //No need to continue to check the array
}
}
return 0;
}
int main()
{
int randomInt;
int generatedNumbers[4];
//We set "0" in all the array, to be sure that the array doesn't contain unknown datas when we create it
memset(generatedNumbers, 0x0, sizeof(generatedNumbers));
srand(time(0));
for (int i = 0; i < 4; ++i) {
randomInt = rand() % 4 + 1;
//As long as the number you generate has already been generated, generate a new one
while(hasMyNumberAlreadyBeenGenerated(randomInt, generatedNumbers, i) == 1){
randomInt = rand() % 4 + 1;
}
printf("generated : %d\n", randomInt);
}
return 0;
}
The problem with this method is that you can't generate a 0, because if you do you'll endlessly loop.
You can bypass this problem using a dynamic array using malloc() function.
If you want to write clean code you should define how many numbers you want to generate with a #define.
What you seem to be asking is a non-random set of numbers 0 to 3 in a random order. Given that;
int set[] = {0, 1, 2, 3 } ;
int remaining = sizeof(set) / sizeof(*set) ;
while( remaining != 0 )
{
int index = rand() % sizeof(set) / sizeof(*set) ;
if( set[index] > 0 )
{
printf( "%d\n", set[index] ) ;
set[index] = -1 ;
remaining-- ;
}
}
For very large sets, this approach may not be practical - the number of iterations necessary to exhaust the set is non-deterministic.

Kadane's algorithm for printing the elements of the maximum subarray found?

I modified the Kadane's algorithm to the following so that it works even in the case wherein I have all negative numbers in the array.
//Largest Sum Contiguous Subarray
#include <iostream>
#include <map>
#include <vector>
#include <string>
#include <utility>
#include <algorithm>
using namespace std;
#define ll long long
#define pb push_back
#define mp make_pair
#define F(i,a,b) for(int i = (int)(a); i < (int)(b); i++)
#define RF(i,a,b) for(int i = (int)(a); i >= (int)(b); i--)
#define SIZE 100000
int main (void)
{
vector<int> myvec;
int arr[SIZE];
int index[SIZE] = {0};
int n;
cin>>n;
F(i,0,n)
{
cin>>arr[i];
}
int maxendinghere = arr[0];
int maxsofar = arr[0];
F(i,1,n)
{
if (arr[i] > (arr[i]+maxendinghere))
myvec.pb(i); // used for finding the elements of the subarray
maxendinghere = max(arr[i],arr[i]+maxendinghere);
maxsofar = max(maxendinghere,maxsofar);
}
cout<<maxsofar<<"\n";
auto it = myvec.begin(); // printing the subarray
while (it != myvec.end())
{
cout<<*it<<"\t";
it++;
}
cout<<"\n";
return 0;
}
Now, I am trying to print the actual elements that form the subarray. One thing that I was able to think of was that the everytime (arr[i]+maxendinghere) will be greater than arr[i], a new element will be a part of the subarray and I push that in a vector and print the elements. But this doesn't give out the actual subarray correctly. What am I missing in this thought process? Thanks!
PS: I understand this is not the best coding style, but this was asked in an interview and I was trying to code it. I couldn't back then and hence this is what I was able to come up with.
Edit: Answer) I was able to code it up after the answer given by templatetypedef. The folllowing is the implementation.
//Largest Sum Contiguous Subarray
#include <iostream>
#include <map>
#include <vector>
#include <string>
#include <utility>
#include <algorithm>
using namespace std;
#define ll long long
#define pb push_back
#define mp make_pair
#define F(i,a,b) for(int i = (int)(a); i < (int)(b); i++)
#define RF(i,a,b) for(int i = (int)(a); i >= (int)(b); i--)
#define SIZE 100000
int main (void)
{
int currsum[SIZE],maxsumsofar[SIZE],sindex[SIZE],eindex[SIZE];
int arr[SIZE];
int start,end,n;
cin>>n;
F(i,0,n)
{
cin>>arr[i];
}
currsum[0] = arr[0];
maxsumsofar[0] = arr[0];
sindex[0] = 0;
eindex[0] = 0;
F(i,1,n)
{
if (arr[i] > (arr[i]+currsum[i-1])) // for starting index
sindex[i] = i;
else
sindex[i] = sindex[i-1];
currsum[i] = max(arr[i],arr[i]+currsum[i-1]);
maxsumsofar[i] = max(currsum[i],maxsumsofar[i-1]);
if (arr[i] > (arr[i]+currsum[i-1]))
eindex[i] = i;
else
{
if (maxsumsofar[i] == maxsumsofar[i-1])
eindex[i] = eindex[i-1];
else
eindex[i] = i;
}
}
cout<<maxsumsofar[n-1]<<"\n";
F(i,0,n)
{
if (maxsumsofar[i] == maxsumsofar[n-1])
{
start = sindex[i];
end = eindex[i];
break;
}
}
cout<<"The array lies between indices "<<start<<" to "<<end<<"\n";
return 0;
}
Kadane's algorithm works by maintaining the start position of a subarray and repeatedly looking at the next element in the array and deciding to either
extend the subarray by appending that element, or
discarding the subarray and starting a new subarray after that element.
If you explicitly keep track of the start point of the current subarray (initially it's before the first element of the array, and it resets every time that the total drops below zero), it shouldn't be too hard to find the optimal subarray. Every time you update the maximum subarray found, you either
have just appended a new element to the existing maximum subarray (so just append to the best thing you've found so far), or
have found a new subarray that starts at a different position than the previous best subarray, so throw out the old max and replace it with this new one.
You can implement this by tracking not just the maximum subarray so far, but also its start position. You're in case (1) if the max subarray starts at the same position as your current array and case (2) otherwise.

Randomly choose two elements from array and swap values in C

I'm writing a program where part of the instructions is to randomly choose two different ord[] elements and then swap their contents. I'm firstly having issues even generating a random element from the array, let alone swapping them (I can't even get it to print the random values). What am I doing wrong? I'm sorry if I'm messing everything up completely. Here is what I have so far:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
#define MMAX 5;
#define ORD_SIZE ( sizeof((ord)) / sizeof((ord[0])) )
int randomOne = 0;
int randomTwo = 0;
int ord[MMAX];
srand(time(NULL));
randomOne = ord[rand() % ORD_SIZE];
randomTwo = ord[rand() % ORD_SIZE];
printf("%d", randomOne);
printf("%d", randomTwo);
int tmp = 0;
tmp = randomOne;
randomOne = randomTwo;
randomTwo = tmp;
printf("%d", ord[randomOne]);
printf("%d", ord[randomTwo]);
return 0;}
You have 2 big problems:
You need to generate random indices and swap the elements at those indices, not take 2 random elements of the array:
.
randomOne = rand() % ORD_SIZE;
randomTwo = rand() % ORD_SIZE;
printf("%d", ord[randomOne]);
printf("%d", ord[randomTwo]);
int temporary = ord[randomOne];
ord[randomOne] = ord[randomTwo];
ord[randomTwo] = temporary;
Your array, ord, is not initialized.
Also, take a look at http://blog.codinghorror.com/the-danger-of-naivete/. Your "randomness" may be a bit biased towards certain indices.

Minimum calls to rand() C

Edit:
Sorry for the inconvinience that made because of my undetailed question.
So, i have an array of numbers (int) with 1000 cells (index 0-999)
and I need to fill all the cells of the array with unique random numbers by calling the rand() function in C, but i have to do it with only 1000 calls to the fuction.. (Every number that generated is inserted to the array), there cant be duplicated numbers in the array.
Any ideas how I can do it?
Note:
Here is a sample code to fill the array without limiting the number of calls to rand.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define DO_RAND rand()%1000
#define ARR_SIZE 1000
int main()
{
int i,callToRand=0,j;
int array[ARR_SIZE];
srand(time(NULL));
for(i=0;i<ARR_SIZE;i++) //Runs on the whole array
{
array[i]=DO_RAND; //inserting random number to the array
callToRand++; //increasing the number of calls to rand() function
for(j=0;j<i;j++) //running on the array till the current cell
{
if(array[j]==array[i])
//checking if the number has already in the array.
{
array[i]=DO_RAND;
callToRand++;
j=-1; //staring the checker loop again
}
}
}
printf("The number of calls to the function rand() were: %d\n",callToRand);
system("PAUSE");
return (0);
}
Having finally stated that you want an array of unique numbers within the range of the array size, try this. Note that the numbers are not randomised - they are defined - the sequence is.
Your posted attempt was very inefficient, using two nested loops. This uses one loop to initialise the array and another to randomise the sequence. No need to count the calls to rand() which are obviously ARR_SIZE.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ARR_SIZE 100 //1000
int main()
{
int i, j, temp;
int array[ARR_SIZE];
srand((unsigned)time(NULL));
for(i=0; i<ARR_SIZE; i++) // set up unique array
array[i] = i;
for(i=0; i<ARR_SIZE; i++) { // randomize the sequence
j = rand() % ARR_SIZE; // pick another (or same) index
temp = array[i]; // and swap the values
array[i] = array[j];
array[j] = temp;
}
for(i=0; i<ARR_SIZE; i++) // show results
printf ("%5d", array[i]);
printf ("\n");
return (0);
}

Resources