Quicksort-ing random numbers - c

I want to Quicksort a randomly generated array (homework). I'm given a function "randomArray" which generates the random array. However, I don't get correct results. Can anyone point out what's wrong with my code?
There might be a problem with pointers in my code. I don't understand very well why the (given) "randomArray" function takes a pointer variable.
#ifndef UTIL_H
#define UTIL_H
#include <time.h>
#include <sys/time.h>
#include <stdlib.h>
#define MIN 0
#define MAX 100000
void quicksort(double *a[], int n)
{
if (n <= 1) return;
double *p = a[n/2];
double *b[n], *c[n];
int i, j = 0, k = 0;
for (i=0; i < n; i++) {
if (i == n/2) continue;
if ( a[i] <= p) b[j++] = a[i];
else c[k++] = a[i];
}
quicksort(b,j);
quicksort(c,k);
for (i=0; i<j; i++) a[i] =b[i];
a[j] = p;
for (i= 0; i<k; i++) a[j+1+i] =c[i];
}
void
randomArray (double *array, int length)
{
int i ;
for (i = 0; i < length; i++)
{
array[i] =
(double) (rand () /
(((double) RAND_MAX + 1) / (double) (MAX - MIN + 1))) + MIN;
}
}
int main(void) {
int i;
/* das Array zum Sortieren */
double test_array[9];
randomArray(test_array, 9);
quicksort(test_array, 9);
for(i = 0; i < 9; i++)
printf("%f ", test_array[i]);
printf("\n");
return 0;
}

You allocate an array in the main function:
double test_array[9];
When passing an array to a function
randomArray(test_array, 9);
It decays to a pointer, that's why you also need to pass its length:
randomArray (double *array, int length)

Related

Trying to get the Average Execution Time of a function, but the recorded value ends up as 0

I'm trying to get the average execution time of a function, but whenever I get a single lap of the function in, the recorded time ends up being 0. Even after calling the function 100 times, the recorded execution time for each call is 0. Is there something missing in my code to get the execution time of this function?
Driver.c
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "generateSuffixArray.c"
#include "selectionsort.c"
void DataReset(int A[], int B[], int n){
int i;
for(i = 0; i < n; i++)
{
B[i] = A[i];
}
}
double getAverage(double Laps[], int iterations)
{
int j;
double sum = 0.0, Average;
for(j = 0; j < iterations; j++)
{
sum+=Laps[j];
}
Average = sum/iterations;
return Average;
}
void main(){
int n = 10, k = 100, i, j;
double elapsed;
double Laps[k];
char String[n+1];
int indices[n];
int copy[n];
clock_t start, end;
memset(String, '\0', sizeof(String));
generateSuffixArray(n, indices, String);
DataReset(indices, copy, n);
for(i = 0; i < 2; i++){
for(j = 0; j < k; j++){
start = clock();
if(i == 0){
if(j == 0){
printf("------Selection Sort------\n");
}
startSS(n, indices, String);
}
end = clock();
DataReset(copy, indices, n);
elapsed = ((double) (end - start) / CLOCKS_PER_SEC);
elapsed *= 1000;
Laps[j] = elapsed;
printf("MET = %1f\n", elapsed);
}
}
}
generateSuffixArray.c
#include <stdio.h>
#include <string.h>
#include <time.h>
// --- Print Function to test array content ---//
/*void printSuffixes(int N, int SArray[], char String[]){
int i;
printf("%s\n", String);
for(i = 0; i < N; i++){
printf("%d", SArray[i]);
}
printf("\n");
}*/
// --- From alphabet {a, c, g, t} --- //
void generateSuffixArray(int N, int SArray[], char String[])
{
int i, charNo;
srand(time(NULL));
for(i = 0; i < N; i++)
{
charNo = rand() % (4 - 1 + 1) + 1;
switch(charNo){
case 1: String[i] = 'a';
break;
case 2: String[i] = 'c';
break;
case 3: String[i] = 'g';
break;
case 4: String[i] = 't';
break;
default: charNo = rand() % (4 - 1 + 1) + 1;
i--;
}
SArray[i] = i;
}
//printSuffixes(N, SArray, String);
}
selectionsort.c
#include <stdio.h>
#include <string.h>
void switcher(int *xp, int *yp){
int temp = *xp;
*xp = *yp;
*yp = temp;
}
void selectionSort(int n, int indices[], char arr[]){
int i, j, min_idx, curr_idx, key_idx;
char key[n], temp[n];
// One by one move boundary of unsorted subarray
for (i = 0; i < n-1; i++)
{
// Find the minimum element in unsorted array
key_idx = indices[i];
strncpy(key, arr + indices[i], strlen(arr) - indices[i]);
key[strlen(key)+1] = '\0';
for (j = i+1; j < n; j++){
strncpy(temp, arr + indices[j], strlen(arr) - indices[i]);
temp[strlen(temp)+1] = '\0';
if(strcmp(key, temp) < 0){
min_idx = j;
strncpy(key, arr + indices[j], strlen(arr) - indices[j]);
key[strlen(key)+1] = '\0';
}
}
// Swap the found minimum element with the first element
switcher(&indices[min_idx], &indices[i]);
}
}
/* UTILITY FUNCTIONS */
// --- Function to print the sorted array --- //
void printArray(int size, int arr[]){
int i, j;
for (i=0; i < size; i++){
printf("%d", arr[i]);
}
}
// --- Start of Insertion Sort process --- //
int startSS(int n, int indices[], char arr[]){
selectionSort(n, indices, arr);
//printArray(n, indices);
}

Determine the number of elements that belongs to a user-defined range of values

Need to solve a problem in C. It is required to create a two-dimensional array (3x3) whcih will be filled with random values in range (-16, 27). And then i should write a function which determines the number of elements that belongs to a user-defined range of values.
Tried to do on my own, but couldn't. Help, please!
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// function to count elements within given range
int countInRange(int arr[9], int n, int x, int y)
{
// initialize result
int count = 0;
for (int i = 0; i < n; i++) {
// check if element is in range
if (arr[i] >= x && arr[i] <= y)
count++;
}
return count;
}
// driver function
int main()
{
srand(time(NULL));
int arr[9];
int i;
int size = sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < size; i++) {
arr[i] = rand() % 25 + 16;
}
return 0;
countInRange(arr, 9, 5, 25);
}
Create the 2D array instead of 1D array
Use the correct type for sizes (size_t)
Calling the function after the return makes no sense at all.
size_t getNumber(size_t rows, size_t cols, int (*array)[cols], int min, int max)
{
size_t num = 0;
if(rows && cols && array)
{
for(size_t r = 0; r < rows; r++)
for(size_t c = 0; c < cols; c++)
if(array[r][c] >= min && array[r][c] <= max) num++;
}
return num;
}
// driver function
int main()
{
srand(time(NULL));
int arr[3][3];
size_t i;
size_t size = sizeof(arr) / sizeof(arr[0][0]);
for (i = 0; i < size; i++) {
arr[i/3][i%3] = rand() % 25 + 16;
printf("[%d]%c", arr[i/3][i%3], (i+1) % 3 ? ' ' : '\n');
}
printf("Number of elements in range : %zu\n", getNumber(3, 3, arr, 5, 25));
return 0;
}
https://godbolt.org/z/Mc5YfME7r

generate all permutations with repetition....non-recursive in C

So I would like to know how to write a non-recursive function to print all permutations given an N and r where r^N gives you the total number of permutations.
Example: N = 3, r = 2, total permutations = 8
output:
000
001
010
011
100
101
110
111
This is what I tried but of course it only works for one case:
void perm_iter(int N, int nr_vals){
int pos = N-1;
int i,j,k;
int P_array[N];
for(i=0;i<N;i++){
P_array[i] = 0;
}
int val_array[nr_vals];
for(i=0;i<nr_vals;i++){
val_array[i] = i;
}
do{
for(i=0;i<N;i++){
for(j=0;j<nr_vals;j++){
P_array[pos-1] = val_array[j];
for(k=0;k<nr_vals;k++){
P_array[pos] = val_array[k];
for(i=0;i<N;i++){
printf("%d",P_array[i]);
}
printf("\n");
}
}
pos--;
}
}while(pos > 0);
}
This is an odometer function with variable radix, not really a permutation.
#include <stdio.h>
#include <stdlib.h>
void show(int *a, int n)
{
int i;
for(i = 0; i < n; i++)
printf("%1d", a[i]);
printf("\n");
}
void gen_all_numbers(int r, int n)
{
int i;
int *a;
if(r < 2 || n < 1) /* parameter check */
return;
r -= 1; /* r = max digit value */
a = malloc(n * sizeof(int));
for(i = 0; i < n; i++) /* start with all zeroes */
a[i] = 0;
show(a, n);
while(1){
i = n - 1;
while(a[i] < r){ /* increment last digit */
a[i]++;
show(a,n);
}
/* find next digit to increment */
while(i >= 0 && a[i] == r)
i--;
if(i < 0)break; /* return if done */
a[i]++;
while(++i < n) /* zero following digits */
a[i] = 0;
show(a,n);
}
free(a);
}
int main()
{
gen_all_numbers(2,4);
return 0;
}
This works. Just make sure you use the -lm option when compiling or you'll get an error about the pow function.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void perm(double r,double N){
double num=pow(r,N);
int count=(int)num;
int n=0,b=0;
for (n=0;n<count;n++){
printf("%d: ",n);
for (b=2;b>=0;b--){ //go through bits 2 to 0.
if (n & (1<<b)){printf("1");}else{printf("0");}
}
printf("\n");
}
}
int main(){
perm(2,3);
return 0;
}

Radix sort for 10^6 array in C [duplicate]

This question already has answers here:
Understanding memory allocation, test program crashing
(4 answers)
Closed 7 years ago.
i have this code and it crash in the middle of processing. System gives message "filename.exe stopped working. What is wrong here?
I declare array as global to be able to have so big number of elements, but still it doesn't work.
#include <stdio.h>
#include <stdlib.h>
#define MAX 1000000
#define SHOWPASS
void print(int *a, int n) {
int i;
for (i = 0; i < n; i++)
printf("%d\t", a[i]);
}
void radix_sort(int *a, int n) {
int i, b[MAX], m = 0, exp = 1;
for (i = 0; i < n; i++) {
if (a[i] > m)
m = a[i];
}
while (m / exp > 0) {
int box[10] = { 0 };
for (i = 0; i < n; i++)
box[a[i] / exp % 10]++;
for (i = 1; i < 10; i++)
box[i] += box[i - 1];
for (i = n - 1; i >= 0; i--)
b[--box[a[i] / exp % 10]] = a[i];
for (i = 0; i < n; i++)
a[i] = b[i];
exp *= 10;
#ifdef SHOWPASS
printf("\n\nPASS : ");
print(a, n);
#endif
}
}
int arr[MAX];
int main() {
//int arr[MAX];
int i, num;
printf("\nEnter total elements (num < %d) : ", MAX);
scanf("%d", &num);
printf("\ncreate array : ");
for (i = 0; i < num; i++)
arr[i]=rand()%10;
printf("\nARRAY : ");
print(&arr[0], num);
radix_sort(&arr[0], num);
printf("\n\nSORTED : ");
print(&arr[0], num);
return 0;
}
Here is another code i tried, this time i used malloc. But still it crashes before starting sort. everything is fine if number of elements is <100000.
#include <stdio.h>
#include <stdlib.h>
#define MAX 1000000
#define SHOWPASS
void print(int *a, int n) {
int i;
for (i = 0; i < n; i++)
printf("%d\t", a[i]);
}
void radix_sort(int *a, int n) {
int i, b[MAX], m = 0, exp = 1;
for (i = 0; i < n; i++) {
if (a[i] > m)
m = a[i];
}
while (m / exp > 0) {
int box[10] = { 0 };
for (i = 0; i < n; i++)
box[a[i] / exp % 10]++;
for (i = 1; i < 10; i++)
box[i] += box[i - 1];
for (i = n - 1; i >= 0; i--)
b[--box[a[i] / exp % 10]] = a[i];
for (i = 0; i < n; i++)
a[i] = b[i];
exp *= 10;
#ifdef SHOWPASS
printf("\n\nPASS : ");
print(a, n);
#endif
}
}
int i, num;
int main() {
int* arr = (int*)malloc(MAX * sizeof(int));
int i;
printf("\ncreate array : ");
for (i = 0; i < MAX; i++)
arr[i]=rand()%10;
printf("\nARRAY : ");
print(&arr[0], MAX);
radix_sort(&arr[0], MAX);
printf("\n\nSORTED : ");
print(&arr[0], MAX);
free(arr);
return 0;
}
The bug is here:
int i, b[MAX], m = 0, exp = 1;
Allocating a huge (1 million int) array on the stack is not possible on some if not most systems.
You should malloc the temporary array and allocate only the size needed for the sort, namely n * sizeof(int).
Another problem is this: your radix_sort cannot handle negative numbers.
Less important but worth mentioning: your implementation is not stable. Not a problem for simple int arrays, but potentially incorrect for larger structures.
Furthermore, your code is inefficient: you use division and modulo 10. It would be much faster to use shifting and masking.
Here is a more efficient implementation for large arrays:
#include <limits.h>
#include <string.h>
#include <stdlib.h>
static void radix_sort(int *a, size_t size) {
size_t counts[sizeof(*a)][256] = {{ 0 }}, *cp;
size_t n, i, sum;
unsigned int *tmp, *src, *dst, *aa;
dst = tmp = malloc(size * sizeof(*a));
src = (unsigned int *)a;
for (i = 0; i < size; i++) {
unsigned int v = src[i] + (unsigned int)INT_MIN;
for (n = 0; n < sizeof(*a) * 8; n += 8)
counts[n >> 3][(v >> n) & 255]++;
}
for (n = 0; n < sizeof(*a) * 8; n += 8) {
cp = &counts[n >> 3][0];
if (cp[0] == size) continue;
for (i = sum = 0; i < 256; i++)
cp[i] = (sum += cp[i]) - cp[i];
for (i = 0; i < size; i++)
dst[cp[((src[i] + (unsigned int)INT_MIN) >> n) & 255]++] = src[i];
aa = src;
src = dst;
dst = aa;
}
if (src == tmp) {
memcpy(a, src, size * sizeof(*a));
}
free(tmp);
}

Trouble using pointers to sort array in C

I'm working on a program for class. We are using pointers. We had to generate an array with the number of elements being determined by the user (using malloc). I got that part all working. Second we had to sort the array in descending order. I have no clue why I cant get this to work. This code flips the whole array, so that 3 4 5 12 5 becomes 5 12 5 4 3, but that is not what I want. I'm sure it's something small, but for the life of me I cant figure out what I'm doing wrong.
void main()
{
int *p, *sizearray, *q;
int i, siz;
printf("How large do you want the array? Enter a number between 0 and 50\n");
scanf("%d", &siz);
if (siz <= 50)
{
p = genarr(siz);
for (i = 0; i <siz; i++)
printf("%i\n", *(p + i));
arrsort(p,siz);
for (i = 0; i <siz; i++)
printf("%i\n", *(p + i));
}
else
printf("That number was not in the given range");
while(1);
}
#include "stdafx.h"
#include <time.h> // required for the time_t structure
#include <stdlib.h> // Reqwuired for the srand() and rand() functions
#include "ArrEdit.h"
int* genarr(int size)
{
time_t t;
int i, m;
int *sizearr;
sizearr = (int*)malloc(sizeof(int)*size);
srand((unsigned)time(&t));
for (i = 0; i<size; i++)
*(sizearr + i) = rand() % 50;
return sizearr;
free(sizearr);
}
int *arrsort(int*prt, int si)
{
int k, j;
int temp; // holding variable
for (k = 0; k< (si - 1); k++) // element to be compared
for (j = (k + 1); j < si; j++) // rest of the elements
{
swap(&prt[k], &prt[j]);
}
return prt;
}
void swap(int *s, int *r)
{
int pSwap = *r;
*r = *s;
*s = pSwap;
}
for (j = (k + 1); j < si; j++) // rest of the elements
{
swap(&prt[k], &prt[j]);
}
This should only swap if k > j, so you need an if statement:
for (j = (k + 1); j < si; j++) // rest of the elements
{
if (prt[k] > prt[j])
swap(&prt[k], &prt[j]);
}

Resources