algorithms c code in time.h and files - c

I have a project for my university. In this project I must make a program in C language for sorting a huge table (30000 integers) with some sorting methods like bubble,quick,straight insertion and straight selection. In the output should be the number of changes in every sorting method and the time that was needed to completed. I have two problems:
I cannot show the time that was needed
I must redirect the output to a file but I don't know how to make it.
Here's the code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 300
int getUniqueNumber(int p[N],int i);
int StraightInsertion(int p[]);
int StraightSelection(int p[]);
int BubbleSort(int p[]);
int quicksort(int left, int right, int p[]);
int main(int argc, char *argv[])
{
FILE *f;
int c,p[N],p2[N];
int i,b;
int t0,t1,dt;
int s=0;
do{
for (i=0;i<N;i++)
p2[i]=getUniqueNumber(p2,i);
for(i=0;i<N;i++)
p[i]=p2[i];
printf("\nTable after sorts:\n");
printf("\n\n\n");
printf("straight selection %d\n",s+1);
time(&t0);
c=StraightSelection(p);
time(&t1);
dt=t1-t0;
printf("\n Number of changes: %d\n",c);
printf(" Processing time: %d\n",dt);
// straight insertion table
for(i=0;i<N;i++)
p[i]=p2[i];
printf("\n\n\n");
printf("straight isertion %d\n",s+1);
time(&t0);
c=StraightInsertion(p);
time(&t1);
printf("\n number of changes: %d",c);
dt=t1-t0;
printf(" Processing time = %f\n",dt);
// Bubble Sort table
for(i=0;i<N;i++)
p[i]=p2[i];
printf("\n\n\n");
printf("Bubble sort %d\n",s+1);
time(&t0);
c=BubbleSort(p);
time(&t1);
printf("\n Number of changes: %d\n",c);
dt=t1-t0;
printf(" Processing time = %f\n",dt);
// Quick Sort table
for(i=0;i<N;i++)
p[i]=p2[i];
printf("\n\n\n");
printf("Quick sort %d",s+1);
time(&t0);
c=quicksort(0,N-1,p);
time(&t1);
dt=t0-t1;
printf("\n Number of changes: %d\n",c);
printf(" Processing time = %f\n",dt);
s++;
}
while(s<20);
return 0;
}
int getUniqueNumber(int p[N],int i)
{
int x,j, found;
srand(time(NULL));
do
{
x = rand();
found = 0;
j = 0;
while (j<=i && found == 0)
{
if (p[j] == x)
found = 1;
else
j++;
}
}while (found == 1);
return x;
}
// STRAIGHT SELECTION
int StraightSelection(int p[])
{
int i,j,k,min=0,a[N];
int count=0;
for (i=0; i<N-1; i++)
{
k = i;
min = p[i];
for (j = i+1; j<N; j++)
{
if (p[j] < min)
{
k = j;
min = p[j];
count ++;
}
}
p[k] = p[i] ;
p[i] = min;
}
return count;
}
//Straight Insertion
int StraightInsertion(int p[])
{
int i,j,x;
int count=0;
for(i=1; i<N; i++)
{
x = p[i];
j = i -1;
while(x<p[j] && j>=0)
{
p[j+1] = p[j];
j = j-1;
count ++;
}
p[j+1] = x;
}
return count;
}
//Bubble Sort
int BubbleSort(int p[])
{
int i,j,temp;
int count;
for (i=1; i<N; i++)
for (j=N-1; j>=i; j--)
if (p[j-1] > p[j])
{
temp = p[j-1];
p[j-1] = p[j] ;
p[j] = temp ;
count ++;
}
return count;
}
//Quick Sort
int quicksort(int left, int right, int p[])
{
int i, j, mid, x, temp;
int count=0;
if (left < right)
{
i = left;
j = right;
mid = (left+right)/2;
x = p[mid];
while (i < j)
{
while (p[i] < x)
i++;
while (p[j] > x)
j--;
if (i < j)
{
if (p[i] == p[j])
{
if (i<mid)
i++;
if (j>mid)
j--;
}
else
{
temp = p[i];
p[i] = p[j];
p[j] = temp;
}
count ++;
}
}
quicksort(left,j-1,p);
quicksort(j+1,right,p);
}
return count;
}

Output redirection in bash can be accomplished with >.
For example, if you want to redirect the output of myprog to the file myout, you would use:
./myprog >myout
To time a program's execution, you can use the time command, like so:
time ./myprog
It will count the total amount of time elapsed since your program started until it exited (usually referred to as the wall-clock time), the amount of time you spend in user-space code and the amount of time spent executing kernel code (executing syscalls, for example, as part of printing the output).
So, to time your program and redirect output to a file, you would do this:
time ./myprog >myout
As others have mentioned in the comments, these are relatively easy tasks, you could probably find this information in a few seconds. Please make sure to do some research in the future before posting new questions. Good luck with your project!
Note: This, of course, assumes you have a different program for each sorting algorithm. If you'd rather stick to a single executable, I suggest you look at Execution time of C program to learn how to time the execution of each function.

Related

reversing a double array with a recursive function in c without loop in the recursive part of the code

I've been trying to reverse a double array with a recursive function without using loops in the recursive part of the code.
I've written the code for integers and it works for all cases, however, I couldn't reverse the elements of the array as doubles
Is there anyone would like to comment on this at least to give a perception?
Thanks
#include <stdio.h>
#include <stdlib.h>
void ArrayReverse(int x[], int N)
{
if (N <= 1)
{
return;
}
else
{
int temp;
int j = 0;
temp = x[j];
x[j] = x[N-1];
x[N-1] = temp;
ArrayReverse(&x[1],N-2);
}
}
int main(int argc, char *argv[]) {
int num_of_el;
int i;
printf("enter the number of elements of the array: \n");
scanf("%d", &num_of_el);
int arr[num_of_el];
int element;
int k,l;
printf("enter the elements one by one: \n");
for(i=0;i <= num_of_el - 1; i++)
{
scanf("%d", &element);
arr[i] = element;
}
for(l=0;l <= num_of_el - 1; l++)
{
printf("%d", arr[l]);
}
printf("\n");
ArrayReverse(arr,num_of_el);
for(k=0;k <= num_of_el - 1; k++)
{
printf("%d", arr[k]);
}
return 0;
}

C heapsort crashes whenever run, windows reports error

I am currently having some trouble with this heapsort, I have no errors on compilation, however, when I run the program, it crashes, as in windows says it crashes, there is no output in the terminal, only the report from windows. Here is the code. The file is a simple line by line file with numbers in it, it has 10,000 elements in it.
#include<stdio.h>
void heapsort(int[],int);
void heapify(int[],int);
void adjust(int[],int);
int main() {
int n,i,a[10000];
// printf("\nEnter the limit:");
FILE *file;
file = fopen("input.txt", "r");
int j=0;
int num;
while(fscanf(file, "%d", &num) > 0) {
a[j] = num;
j++;
}
fclose(file);
// scanf("%d",&n);
// printf("\nEnter the elements:");
// for (i=0;i<n;i++)
// scanf("%d",&a[i]);
heapsort(a,n);
printf("\nThe Sorted Elements Are:\n");
for (i=0;i<n;i++)
printf("\t%d",a[i]);
printf("\n");
return 0;
}
void heapsort(int a[],int n) {
int i,t;
heapify(a,n);
for (i=n-1;i>0;i--) {
t = a[0];
a[0] = a[i];
a[i] = t;
adjust(a,i);
}
}
void heapify(int a[],int n) {
int k,i,j,item;
for (k=1;k<n;k++) {
item = a[k];
i = k;
j = (i-1)/2;
while((i>0)&&(item>a[j])) {
a[i] = a[j];
i = j;
j = (i-1)/2;
}
a[i] = item;
}
}
void adjust(int a[],int n) {
int i,j,item;
j = 0;
item = a[j];
i = 2*j+1;
while(i<=n-1) {
if(i+1 <= n-1)
if(a[i] <a[i+1])
i++;
if(item<a[i]) {
a[j] = a[i];
j = i;
i = 2*j+1;
} else
break;
}
a[j] = item;
}
Local (automatic) variables are not initialised. You are passing n to your function heapsort which was defined but not initialised. I see that the commented out code would have worked, since n was an input value. Better change the j to n to be consistent.
int n,i,a[10000]; // doesn't initialize n, This is just a declaration
Standard ISO/IEC 9899:201x 6.7.9->10 states
If an object that has automatic storage duration is not initialized
explicitly, its value is indeterminate.
Then you're
heapsort(a,n); // calling heapsort with arbitrary n
You might consider changing
fscanf(file, "%d", &num) > 0
to
fscanf(file, "%d", &num) == 1
as you have said :
The file is a simple line by line file with numbers in it, it has
10,000 elements in it.

Dynamic Programming - Minimum Coin caching

Earlier I posted a question about the coin vending machine problem (the minimum number of coins required). Turns out the issue was a typo in a for loop, so now the program works. The original question was this:
As the programmer of a vending machine controller your are required to compute the minimum number of coins that make up the required change to give back to customers. An efficient solution to this problem takes a dynamic programming approach, starting off computing the number of coins required for a 1 cent change, then for 2 cents, then for 3 cents, until reaching the required change and each time making use of the prior computed number of coins. Write a program containing the function ComputeChange(), that takes a list of valid coins and the required change. This program should repeatedly ask for the required change from the console and call ComputeChange() accordingly. It should also make use of “caching”, where any previously computed intermediate values are retained for subsequent look-up.
The issue is that the code makes use of recursion, so it takes quite a long time to evaluate large values. Making use of caching should improve the issue, but I have no idea how to go about it. The code can be found below.
#include <stdio.h>
#include <limits.h>
int computeChange(int[],int,int);
int min(int[],int);
int main(){
int cur[]={1,2,5,10,20,50,100,200};
int n = sizeof(cur)/sizeof(int);
int v;
printf("Enter a value in euro cents: ");
scanf("%d", &v);
printf("The minimum number of euro coins required is %d", computeChange(cur, v, n));
return 0;
}
int computeChange(int cur[], int v, int n){
if(v < 0)
return INT_MAX;
else if(v == 0)
return 0;
else{
int possible_mins[n], i;
for(i = 0; i < n; i++){
possible_mins[i]=computeChange(cur, v-cur[i], n);
}
return 1+min(possible_mins, n);
};
}
int min(int a[], int n){
int min = INT_MAX, i;
for(i = 0; i < n; i++){
if((a[i]>=0) && (a[i]< min))
min = a[i];
}
return min;
}
With your existing code:
#include <stdio.h>
#include <limits.h>
int computeChange(int[],int,int);
int min(int[],int);
void initChange ();
int change [MAX]; //used for memoization
int main(){
int cur[]={1,2,5,10,20,50,100,200};
int n = sizeof(cur)/sizeof(int);
int v;
initChange ();
printf("Enter a value in euro cents: ");
scanf("%d", &v);
printf("The minimum number of euro coins required is %d", computeChange(cur, v, n));
return 0;
}
void initChange () {
int i =0;
for (i = 0; i < MAX; i++) {
change[i] = INT_MAX;
}
}
int computeChange(int cur[], int v, int n){
if(v < 0)
return INT_MAX;
else if(v == 0)
return 0;
else{
if (change[v] == INT_MAX) {
int possible_mins[n], i;
for(i = 0; i < n; i++){
possible_mins[i]=computeChange(cur, v-cur[i], n);
}
change[v] = 1 + min(possible_mins, n); // memoization
}
return change[v];//you return the memoized value
};
}
int min(int a[], int n){
int min = INT_MAX, i;
for(i = 0; i < n; i++){
if((a[i]>=0) && (a[i]< min))
min = a[i];
}
return min;
}
I already posted a solution using loops in your previous question. I will post it again here:
So the below is the code snippet for your problem using memoization and dynamic programming. The complexity is O(Val*numTypesofCoins).
In the end, change[val] will give you the min number of coins for val.
int main (void) {
int change [MAX];
int cur[]={1,2,5,10,20,50,100,200};
int n = sizeof(a)/sizeof(int);
int val; //whatever user enters to get the num of coins required.
printf("Enter a value in euro cents: ");
scanf("%d", &val);
for (i=0; i <= val; i++) {
change[i] = INT_MAX;
}
for (i=0; i < n; i++) { // change for the currency coins should be 1.
change[cur[i]] = 1;
}
for (i=1; i <= val; i++) {
int min = INT_MAX;
int coins = 0;
if (change[i] != INT_MAX) { // Already got in 2nd loop
continue;
}
for (j=0; j < n; j++) {
if (cur[j] > i) { // coin value greater than i, so break.
break;
}
coins = 1 + change[i - cur[j]];
if (coins < min) {
min = coins;
}
}
change[i] = min;
}
}

Bubble sort vs Insertion sort run-time

I'm trying to write a program that calculates the run-time of a bubble sort vs an insertion sort. It takes in two inputs, number of elements and elements, and calculates their run-time. This is what I have so far, but it is printing the same time for both sorters.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
int bubblesort(int a[], int n);
int insertionsort(int a[], int n);
int main()
{
int s,temp,i,j,comparisons,a[20];
float function_time;
clock_t start;
clock_t end;
printf("Enter total numbers of elements: ");
scanf("%d",&s);
printf("Enter %d elements: ",s);
for(i=0;i<s;i++)
scanf("%d",&a[i]);
//Bubble sorting algorithm
for(i=s-2;i>=0;i--)
{
for(j=0;j<=i;j++)
{
if(a[j]>a[j+1])
{
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
for(i=0;i<s;i++)
a[i]= rand()%10000;
start = clock();
comparisons= bubblesort(a, s);
end = clock();
function_time = (float)(end)/(CLOCKS_PER_SEC); // Time in seconds
printf("\nTime for Bubble Sort is %f microseconds\n ", function_time);
// Insertion sorting algorithm
for(i=1;i<s;i++)
{
temp=a[i];
j=i-1;
while((temp<a[j])&&(j>=0))
{
a[j+1]=a[j];
j=j-1;
}
a[j+1]=temp;
}
for(i=0;i<s;i++)
a[i]= rand()%10000;
start = clock();
comparisons= insertionsort(a, s);
end = clock();
function_time = (float)(end)/(CLOCKS_PER_SEC); // Time in seconds
printf("\nTime for Insertion Sort is %f microseconds\n ", function_time);
return 0;
}
int bubblesort(int a[], int n)
{
bool swapped = false;
int temp=0, counter=0;
for (int j = n-1; j>0; j--)
{
swapped = false;
for (int k = 0; k<j; k++)
{
counter++;
if (a[k+1] < a[k])
{
temp= a[k];
a[k] = a[k+1];
a[k+1]= temp;
swapped = true;
}
}
if (!swapped)
break;
}
return counter;
}
int insertionsort(int a[], int n)
{
bool swapped = false;
int temp=0, counter=0;
for (int i=1; i<=n; i++)
{
for (int s=i; s>0; s--)
{
counter++;
if (a[s]<a[s-1])
{
temp=a[s-1];
a[s-1]=a[s];
a[s]=temp;
swapped = true;
}
}
if (!swapped)
break;
}
return counter;
}
Firstly, the way you calculate the sorting time is wrong:
function_time = (float)(end)/(CLOCKS_PER_SEC);
It should be:
function_time = (float)(end-start)/(CLOCKS_PER_SEC);
Secondly, although bubble sort and insertion sort both have O(n square) complexity, time taken should have some difference, they cannot be the same. If the problem persists, you should check the output of clock() function, it may not work in your system.
Edit: I found that your code let user type in the elements manually. So I guess your array can only be relatively small. Sorting small-size array takes very little time so the difference is hard to notice. You should let the elements assigned randomly by code, so that you can generate large array for analysis.

QuickSort doesn't work for large inputs

Can anyone spot a problem with my quick sort implementation below? It seems to fail on arrays with more than 10 or so elements.
void swap(int *p1, int *p2)
{
int temp = *p1;
*p1 = *p2;
*p2 = temp;
}
void generateRandom(int arr[], int size)
{
srand(time(NULL));
int i;
for (i = 0; i < size; i++)
{
arr[i] = rand() % 100;
}
}
int partition(int arr[], int start, int end)
{
int i = start, j = end;
int pivot = arr[start];
for (;;)
{
for (; arr[i] < pivot; i++);
for (; arr[j] > pivot; j--);
if (i < j)
{
swap(&arr[i], &arr[j]);
}
else
{
return j;
}
}
}
void quickSort(int arr[], int start, int end)
{
int part;
if (start < end)
{
part = partition(arr, start, end);
quickSort(arr, start, part);
quickSort(arr, part + 1, end);
}
}
int main()
{
generateRandom(arr, 100);
for (i = 0; i < 100; i++)
{
printf("%d ", arr[i]);
}
printf("\n\n");
quickSort(arr, 0, 99);
for (i = 0; i < 100; i++)
{
printf("%d ", arr[i]);
}
printf("\n\n");
return 0;
}
First, you code doesn't compile. When I made the corrections to make it compile (adding stdio.h, and definitions for arr and i in main) it infinite looped, which it will do if the partition starts and ends with the pivot. You need to increment and decrement before the comparisons rather than after. You can do that by starting with i = start-1 and j = end+1 and changing your inner loops to increment or decrement first, or you can leave them as is and just do an i++ and j-- after the swap -- I did that and the sort works.
Note that your pivot choice is poor for already sorted arrays; you really should be picking the median of 3 or even 9 values.
P.S. Other desirable optimizations: 1) Switch to an insertion sort for small partitions -- the optimal cutoff point is machine-dependent. Another approach is to not sort partitions below a certain size, and then do an insertion sort on the whole array after quicksort is done. It's also possible to use heapsort instead of insertion sort if done carefully; google introsort. 2) quicksort does two recursive calls; eliminate the second one by setting start = part + 1 and looping. 3) Avoid the possibility of stack overflow by quicksorting the larger partition first. 4) Eliminate the first recursive call by using an explicit stack. 5) Inline swap() and partition(). 6) Don't bother with any of that and just call the qsort library routine. :-)
I had the same problem,
but I changed my while loop to do..while and it worked.
This is my new code now.
int partition(int a[], int lo, int hi) {
int v = a[lo], i = lo, j = hi;
do {
do {
i++;
} while(a[i] < v) ;
do {
j--;
}while(a[j] > v) ;
if(i < j) interchange(&a[i], &a[j]);
}while(i < j);
interchange(&a[lo], &a[j]);
return j;
}

Resources