#include<stdio.h>
int find( int, int parent[10] );
int uni( int, int, int parent[10] );
int main()
{
int i, j, k, a, b, u, v, n, ne = 1;
int min, mincost = 0, cost[9][9], parent[9];
printf( "\n\tImplementation of Kruskal's algorithm\n" );
printf( "\nEnter the no. of vertices:" );
scanf( "%d", &n );
printf( "\nEnter the cost matrix:\n" );
for ( i = 1; i <= n; i++ )
{
for ( j = 1; j <= n; j++ )
{
printf( "Enter the cost of the edge(%d,%d)=", i, j );
scanf( "%d", &cost[i][j] );
if ( cost[i][j] == 0 )
{
cost[i][j] = 999;
}
}
}
printf( "The edges of Minimum Cost Spanning Tree are\n" );
while ( ne < n )
{
for ( i = 1, min = 999; i <= n; i++ )
{
for ( j = 1; j <= n; j++ )
{
if ( cost[i][j] < min )
{
min = cost[i][j];
a = u = i;
b = v = j;
}
}
}
u = find( u, parent );
v = find( v, parent );
if ( uni( u, v, parent ) == 1 )
{
printf( "%d edge (%d,%d) =%d\n", ne++, a, b, min );
mincost += min;
}
cost[a][b] = cost[b][a] = 999;
}
printf( "\n\tMinimum cost = %d\n", mincost );
}
int uni( int i, int j, int parent[10] )
{
if ( i != j )
{
parent[j] = i;
return 1;
}
return 0;
}
int find( int i, int parent[10] )
{
while ( parent[i] )
{
i = parent[i];
}
return i;
}
It is not able to calculate u,v,uni... i am able to enter the values but i am getting a message segmentation fault (core dumped). i guess there is some problem with the function find and uni(may be in passing of the array parent)..
Without trying to decipher what the code is actually about (single-letter variables, zero comments, no link to this "Kruskal's algorithm" or anything), and in addition to what I already wrote in my comment about adding printf()s to log intermediate values, checking scanf() return codes, mirroring user input back at the user, and sprinkling your code with assert()s...
int parent[9] is declared, but not initialized. find() uses the (uninitialized) contents. Undefined behaviour right there.
Various "fishy" details, like main() declaring parent[9] and cost[9][9], but the functions declaring parent[10]. You also let the user enter the number of vertices, but happily assume that it won't be more than 9 when you use that number as upper loop bound. If any of your assumptions on the amount of storage provided doesn't hold, you're looking at out-of-bounds accesses.
At this point of the code review I'd toss down the code printout on the desk, and give you one of those long, hard stares...
Related
So i wrote a binary Search Program in C based of the Wikipedia Pseudocode but it keeps returning false even when dealing with Array of just one Element. I cant figure out where it goes wrong. Any help is appreciated! Btw, this is a coding challenge so i did not write the Test Suit myself.
EDIT: The Function is being tested as followed:
int arr[] = {6};
size_t length = sizeof(arr)/sizeof(*arr);
TEST_ASSER((&arr[0] == binary_search(6, arr, length));
int *binary_search(int value, const int *arr, size_t length) {
int L = 0;
int R = length - 1;
static int m;
while(L <= R) {
m = floor((L + R) / 2);
if(arr[m] < value) {
L = m + 1;
} else if(arr[m] > value) {
R = m - 1;
} else { return (&m); }
}
return 0;
}
EDIT: So it worked with the following Code after i removed the const term from the original function. Thanks for all your guys help!
int *binary_search(int value, int *arr, size_t length) {
int L = 0;
int R = length - 1;
static int m;
while(L <= R) {
m = (L + R) / 2; // no floor needed
if(arr[m] < value) {
L = m + 1;
} else if(arr[m] > value) {
R = m - 1;
} else {
return &arr[m];
}
}
return 0; // not found
}
The length of the array is declared as having the type size_t
int *binary_search(int value, const int *arr, size_t length) {
So within the function the variables L, R and m also should be declared as having the type size_t.
Also using the function floor
m = floor((L + R) / 2);
absolutely does not make a sense because the expression (L + R) / 2 has the integer type int.
Declaring the variable m as static also does not make a great sense.
The function should return the position of the found element in the array or the size of the array if such an element is not found.
In this condition
TEST_ASSER((&arr[0] == binary_search(6, arr, length));
there are compared address of the first element of the array arr with the address of the static local variable m. It is evident that these objects occupy different extents of memory. So the condition will always evaluate to logical false.
The function can be declared an defined for example the following way as shown in the demonstrative program below.
#include <stdio.h>
size_t binary_search( const int a[], size_t n, int value )
{
size_t low = 0, high = n;
while ( low < high )
{
size_t middle = low + ( high - low ) / 2;
if ( value < a[middle] )
{
high = middle;
}
else if ( a[middle] < value )
{
low = middle + 1;
}
else
{
return middle;
}
}
return n;
}
int main(void)
{
int a[] = { 6 };
const size_t N = sizeof( a ) / sizeof( *a );
int value = 6;
size_t pos = binary_search( a, N, value );
if ( pos != N )
{
printf( "The value %d is found at position %zu\n", value, pos );
}
else
{
printf( "The value %d is not found.\n", value );
}
value = 5;
pos = binary_search( a, N, value );
if ( pos != N )
{
printf( "The value %d is found at position %zu\n", value, pos );
}
else
{
printf( "The value %d is not found.\n", value );
}
value = 7;
pos = binary_search( a, N, value );
if ( pos != N )
{
printf( "The value %d is found at position %zu\n", value, pos );
}
else
{
printf( "The value %d is not found.\n", value );
}
return 0;
}
The program output is
The value 6 is found at position 0
The value 5 is not found.
The value 7 is not found
Another approach is to define the function such a way that it will return a pointer to the found element in the array or NULL if such an element is not found.
Here is one more demonstrative program.
#include <stdio.h>
int * binary_search( const int a[], size_t n, int value )
{
size_t low = 0, high = n;
while ( low < high )
{
size_t middle = low + ( high - low ) / 2;
if ( value < a[middle] )
{
high = middle;
}
else if ( a[middle] < value )
{
low = middle + 1;
}
else
{
return ( int * )( a + middle );
}
}
return NULL;
}
int main(void)
{
int a[] = { 6 };
const size_t N = sizeof( a ) / sizeof( *a );
int value = 6;
int *pos = binary_search( a, N, value );
if ( pos != NULL )
{
printf( "The value %d is found at position %tu\n", value, pos - a );
}
else
{
printf( "The value %d is not found.\n", value );
}
value = 5;
pos = binary_search( a, N, value );
if ( pos != NULL )
{
printf( "The value %d is found at position %tu\n", value, pos - a );
}
else
{
printf( "The value %d is not found.\n", value );
}
value = 7;
pos = binary_search( a, N, value );
if ( pos != NULL )
{
printf( "The value %d is found at position %tu\n", value, pos - a );
}
else
{
printf( "The value %d is not found.\n", value );
}
return 0;
}
The program output is the same as shown above.
The value 6 is found at position 0
The value 5 is not found.
The value 7 is not found.
the logic of binary search should be like this
int *binary_search(int value, const int *arr, size_t length) {
int L = 0;
int R = length - 1;
static int m;
while(L <= R) {
m = floor((L + R) / 2);
if(arr[m]==value)
{
// element found
}
else if(arr[m] < value) {
L = m + 1;
} else if(arr[m] > value) {
R = m - 1;
}
}
return 0;
}
if while loop executed and not entered inside if(arr[m]==value) means element not in the list
Your return statement returns the address of a local variable: &m. This is definitely wrong, as this memory is no longer allocated after the function returns, and it certainly is not the address that is expected in the driver code you have.
The quick fix is return &arr[m], but like said in comments, it is strange to return the address of an array element.
Just return the index, and adapt the function return type accordingly, and the driver code:
#include <stdio.h>
int binary_search(int value, const int *arr, size_t length) {
int L = 0;
int R = length - 1;
static int m;
while(L <= R) {
m = (L + R) / 2; // no floor needed
if(arr[m] < value) {
L = m + 1;
} else if(arr[m] > value) {
R = m - 1;
} else {
return m;
}
}
return -1; // not found
}
int main(void) {
printf("Hello World\n");
int arr[] = {6, 9, 13, 25};
size_t length = sizeof(arr)/sizeof(*arr);
if (1 == binary_search(6, arr, length)) {
printf("ok!\n");
}
return 0;
}
I have to use the recursive selection sort in order to order different arrays of integers.
These arrays are respectively formed by 100, 1000, 10000, 100000, 200000, 500000 items and can be formed by ordered numbers, partially ordered numbers, inverted ordered numbers and random numbers.
After that I have to calculate the time the algorithm took to order the array.
I have to use recursion, It's a homework.
I created a function that generates the array:
typedef enum {ORINATO, INVERS, PARZ_ORDINATO, RANDOM} Ordine;
int *generaArray(int dimensione, Ordine ordine) {
int i, j, n;
int *array = (int*)malloc(dimensione * sizeof(int));
if (!array){
return NULL;
}
switch (ordine){
case ORINATO:
for (i = 0; i < dimensione; i++){
array[i] = i;
} break;
case INVERS:
n =0;
for ( i = dimensione-1; i >= 0 ; i--) {
array[i] = n;
n++;
}break;
case PARZ_ORDINATO:
for (i = 0; i < dimensione/2 ; i++) {
array[i] = i;
}
for (j = i+1; j <dimensione; j++){
n = rand();
array[j] = n;
};break;
case RANDOM:
for ( i = 0; i <= dimensione ; i++) {
array[i] = rand();
}break;
default:
break;
}
return array;
}
And it works like wonders.
Then I have created the recursive selection sort like follows:
void recursiveSelectionSort(int *array, int dim, int start){
int min=0;
if (start >= dim-1){
return;
}
min = findMin(array, start, start+1, dim);
swap(&array[min], &array[start]);
recursiveSelectionSort(array, dim, start+1);
}
int findMin(int *array, int min, int start, int dim){
if(start == dim ){
return min;
}
if (array[start]< array[min]){
min = start;
}
return findMin(array, min, start+1, dim);
}
void swap (int* x, int *y){
int temp = *x;
x = *y;
y = *temp;
}
Now, this as well should work but something clearly isn't. Let's make an example with the implementation, this is what i put in my main:
int main() {
int *array;
clock_t start, end;
double t;
array = generaArray(1000, ORINATO);
start = clock();
recursiveSelectionSort(array, 1000, 0);
end = clock();
t = ((double) (end - start)) / CLOCKS_PER_SEC;
printf("\nIl tempo impiegato per 1000 elementi รจ: %lf secondi", t);
return 0;
}
This works (but it's slower thank it should be). However if you try and change the dimension from 1000 to 200000 or 500000 it shows error 11.
What is it causing it? I tried everything but it doesn't seem to work.
For starters recursive functions called for large arrays can invoke a stack overflow.
So use non-recursive functions that implement the method selection sort for large arrays.
As for your implementation then for example the function swap has typos.
void swap (int* x, int *y){
int temp = *x;
x = *y;
y = *temp;
}
I think you mean
void swap (int* x, int *y){
int temp = *x;
*x = *y;
*y = temp;
}
All other functions have too many parameters.
For example the function findMin can be declared the following way
size_t findMin( const int *a, size_t n );
and can be also defined as a recursive function (if you decided to write recursive functions then this function can be also recursive)
Here is a demonstrative program that shows how the functions can be defined
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void swap( int *x, int *y )
{
int temp = *x;
*x = *y;
*y = temp;
}
size_t findMin( const int a[], size_t n )
{
if ( n < 2 )
{
return 0;
}
else
{
size_t i = findMin( a + 1, n - 1 ) + 1;
return a[i] < a[0] ? i : 0;
}
}
void recursiveSelectionSort( int a[], size_t n )
{
if ( !( n < 2 ) )
{
size_t i = findMin( a + 1, n - 1 ) + 1;
if ( a[i] < a[0] ) swap( &a[0], &a[i] );
recursiveSelectionSort( a + 1, n - 1 );
}
}
int main(void)
{
enum { N = 15 };
int a[N];
srand( ( unsigned int )time( NULL ) );
for ( size_t i = 0; i < N; i++ )
{
a[i] = rand() % N;
}
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
recursiveSelectionSort( a, N );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
return 0;
}
The program output might look like
11 9 3 5 6 8 2 4 5 3 7 9 2 0 14
0 2 2 3 3 4 5 5 6 7 8 9 9 11 14
I'm trying to implement a bucket sort using a resizable vector function that I made. The vector works fine, but I get a segmentation fault anytime I try to run my sort function. Can anyone help me remedy this?
Notes about code: K=# of buckets in this case 10. find_max and find_min do exactly what you'd expect. vector_int_construct initializes an array and vector_int_push_back pushes integers to the end of the array. vector_int_sort just calls on a merge_sort function I created that also works fine on its own.
typedef struct {
size_t size;
size_t maxsize;
int* array;
}
vector_int_t;
void bucket_sort( int* a, size_t size )
{
int min = find_min( a, size );
int max = find_max( a, size );
size_t range = (( max - min ) / K );
vector_int_t buckets[K];
for( size_t i = 0; i < K; i++ ) {
vector_int_construct( &buckets[i] );
for( size_t j = 0; j < range; j++ ) {
vector_int_push_back( &buckets[i], a[j] );
}
}
for( size_t i = 0; i < K; i++ ) {
vector_int_sort( &buckets[i] );
}
size_t cnt = 0;
while( cnt != size ) {
for( size_t i = 0; i < K; i++ ) {
for( size_t j = 0; j < vector_int_size( &buckets[i] ); j++ ) {
a[cnt] = buckets[i].array[j];
cnt++;
}
}
}
}
int main()
{
size_t size = 4;
int a[] = { 19, 95, 4, 23 };
// Print out array before
printf( "Before sorting: " );
ece2400_print_array( a, size );
// Call sort
bucket_sort( a, size );
// Print out array after
printf( "After sorting: " );
ece2400_print_array( a, size );
return 0;
}
I apologize if this question seems too vague, but I am a complete beginner and I am stuck on how to count instances of numbers from an array.
I have a function called create_hist() which has three inputs: an input double array for which the numbers range from 0 to 16, an input integer which indicates how many elements are in the array, and an output integer array of size 17. The goal is to count how many of each numbers are in the first array, and then assign that number to the correct index of the output array i.e:
If the input array contains {0,1,1,2,3,4,4} then the count will be 7, and the output array should be {1,2,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0}.
I am very new to C programming and I don't know where to start. My thoughts were that I could iterate through each element in the input array, and if the element was equal to zero, then add 1 to the first index of the output array and so on. I know this is wrong but I don't know another way. Could someone please guide me on how I could begin this? My first attempt is below.
int create_hist( double input_array[], int count, int hist[17] ) {
for ( int i = 0; i < count; i++ ) {
if ( input_array[i] == 0; ) {
// then add 1 to hist[0]
}
if ( input_array[i] == 1; ) {
// then add 1 to hist[1]
// etc.
}
}
You're not a million miles away from a good solution. If you already have count available to pass in, that's handy. Otherwise, you can replace it with:
sizeof(input_array)/sizeof(double)
If you know for sure the maximum value that can appear in input array, then the rest of the problem should be pretty easy.
Loop through each item in input_array, like you're already doing. Then increment the index of histwhich relates to the value of the current item, like so:
for(int i = 0; i<count; i++){
hist[input_array[i]]++;
}
This should give the output you're looking for. For future reference, this is called a count occurrence algorithm.
The function can look the following way
size_t create_hist( const double in[], size_t n, int out[] )
{
const size_t N = 17;
memset( out, 0, N * sizeof( *out ) );
for ( size_t i = 0; i < n; i++ ) ++out[( size_t )in[i]];
size_t m = 0;
for ( size_t i = 0; i < N; i++ )
{
if ( out[i] ) ++m;
}
return m;
}
Here is a demonstrative program
#include <stdio.h>
#include <string.h>
#define SIZE 17
size_t create_hist( const double in[], size_t n, int out[] )
{
const size_t N = SIZE;
memset( out, 0, N * sizeof( *out ) );
for ( size_t i = 0; i < n; i++ ) ++out[( size_t )in[i]];
size_t m = 0;
for ( size_t i = 0; i < N; i++ )
{
if ( out[i] ) ++m;
}
return m;
}
int main(void)
{
double a[] = { 0, 1, 1, 2, 3, 4, 4 };
int b[SIZE];
size_t n = create_hist( a, sizeof( a ) / sizeof( *a ), b );
printf( "There are %zu unique elements\n", n );
for ( size_t i = 0; i < SIZE; i++ ) printf( "%d ", b[i] );
putchar( '\n' );
return 0;
}
Its output is
There are 5 unique elements
1 2 1 1 2 0 0 0 0 0 0 0 0 0 0 0 0
Hello i'm trying for about 2 hours to create a program which will remove even numbers from a dinamyc allocated array(with malloc)in c.Can somebody help me with some tips or create the code.
p.s. this is my first topic here, so feel free to give me some tips about how to correctly post a qustion.
Let's assume that you already allocated dynamically an array of n elements and initialized it.
In this case the function that removes elements with even values can look the following way
size_t remove_even( int *a, size_t n )
{
size_t m = 0;
for ( size_t i = 0; i < n; i++ )
{
if ( a[i] % 2 != 0 )
{
if ( i != m ) a[m] = a[i];
++m;
}
}
return m;
}
It can be called the following way
size_t m = remove_even( p, n );
for ( size_t i = 0; i < m; i++ ) printf( "%d ", a[i] );
printf( "\n" );
where p is the pointer to your dynamically allocated array of n elements.
The function actually removes nothing. It simply moves odd elements to the beginning of the array.
You can then use standard C function realloc to delete physically the removed elements.
For example
int *tmp = realloc( p, m * sizeof( int ) );
if ( tmp != NULL ) p = tmp;
Here is a demonstrative program
#include <stdlib.h>
#include <stdio.h>
size_t remove_even( int a[], size_t n )
{
size_t m = 0;
for ( size_t i = 0; i < n; i++ )
{
if ( a[i] % 2 != 0 )
{
if ( i != m ) a[m] = a[i];
++m;
}
}
return m;
}
#define N 10
int main( void )
{
int *a = malloc( N * sizeof( int ) );
for ( size_t i = 0; i < N; i++ ) a[i] = i;
for ( size_t i = 0; i < N; i++ ) printf( "%d ", a[i] );
printf( "\n" );
size_t m = remove_even( a, N );
int *tmp = realloc( a, m * sizeof( int ) );
if ( tmp != NULL ) a = tmp;
for ( size_t i = 0; i < m; i++ ) printf( "%d ", a[i] );
printf( "\n" );
free( a );
}
Its output is
0 1 2 3 4 5 6 7 8 9
1 3 5 7 9
There are some things which you need to check before you try to code something, but I see that there is no code which you showed use.
SO is not a tutorial site, so this means that you should show us some code which actually does compile and ask here if there are some problems with that code.
Any way until than, this code should give you an Idea about how to check if a Number is odd or even:
#include<stdio.h>
#include<stdlib.h>
int main(void){
int n;
printf("Enter an integer:> ");
if((scanf("%d", &n)) != 1){
printf("Error, Fix it!\n");
exit(1);
}
if (n%2 == 0){
printf("Even\n");
}else{
printf("Odd\n");
}
return 0;
}
The whole story here is not about checking if Numbers inside an Array are odd or even, is about to find a way to check if a number is odd or even and only then you should check if inside that array there are odd or even numbers. I hope you understand my point.
One easy way to remove even numbers from an array in C is to create a new array of all odd elements starting from 1 to the maximum element present in the original array and then compare the original array and odd elements array (and do intersection) and put it in another array with same elements present in both arrays.
Here is the program:
#include<stdio.h>
int main(){
int a[20],n,i,max,j,k=0,l=0;
printf("enter limit of array ");
scanf("%d",&n);
printf("enter the elements ");
for (i=0;i<n;i++){
scanf("%d",&a[i]);
}
max=a[0];
for (i=0;i<n;i++){
if (a[i]>max){
max=a[i];
}
}
int b[max],c[n],count=0;
for (j=2;j<=max;j=j+2){
c[k++]=j;
count++;
}
for (i=0;i<n;i++){
for (j=0;j<count;j++){
if (a[i]==c[j])
b[l++]=a[i];
}
}
for (i=0;i<count;i++){
printf("%d ",b[i]);
}
return 0;
}