I've tried to sort 5 integers array using GOTO (using in for the first time) and if statement only,
but I've debugged this code and I couldn't figure why that's not working, I don't fully understant how to use the GOTO and why I've got stuck inside the swapp loop, any help ?
int* sort5integersIFGOTO(int* arr)
{
int i = 0, j = 1;
start:
if (arr[i] > arr[j])
goto swapp;
swapp:
swap(&arr[i], &arr[j]);
if (j < 4)
{
j++;
goto start;
}
if (i < 3)
{
i++;
j = i+1;
goto start;
}
return arr;
}
This piece of code:
if (arr[i] > arr[j])
goto swapp;
swapp:
swap(&arr[i], &arr[j]);
alwayds does the same thing -- if the test is true, it jumps to the label (on the very next line) and if the test is false, it falls through to the label. So the result of the comparison is irrelevant, and it always swaps. You probably want
if (arr[i] > arr[j])
swap(&arr[i], &arr[j]);
with no label or goto here at all...
For starters try always to write more general functions that for example can sort arrays of various sizes.
Also the return type int * of the function sort5integersIFGOTO does not make a great sense. Usually such functions have the return type void.
Your function is incorrect. For example if arr[i] is not greater than arr[j] nevertheless the control is passed to the statement under the label swapp that follows the if statement and in any case two elements of the array are swapped.
start:
if (arr[i] > arr[j])
goto swapp;
swapp:
swap(&arr[i], &arr[j]);
Also within the function there are used unclear magic numbers as 3 and 4 though the passed array as it follows from the description has 5 elements.
The function can be defined the following way as it is shown in the demonstration program below.
#include <stdio.h>
void swap( int *a, int *b )
{
int tmp = *a;
*a = *b;
*b = tmp;
}
void sort5integersIFGOTO( int *arr, size_t n )
{
size_t i = 0;
start:
if ( i < n )
{
size_t j = i;
next:
if ( ++j < n )
{
if ( arr[j] < arr[i] )
{
swap( arr + i, arr + j );
}
goto next;
}
else
{
++i;
goto start;
}
}
}
int main(void)
{
int arr[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
const size_t N = sizeof( arr ) / sizeof( *arr );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", arr[i] );
}
putchar( '\n' );
sort5integersIFGOTO( arr, N );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", arr[i] );
}
putchar( '\n' );
}
The program output is
9 8 7 6 5 4 3 2 1 0
0 1 2 3 4 5 6 7 8 9
As you can see neither magic number is used within the function. The function can sort arrays of various sizes.
It is not difficult to rewrite the function using for loops instead of goto statements. For example
void sort5integersIFGOTO( int *arr, size_t n )
{
for ( size_t i = 0; i < n; i++ )
{
for ( size_t j = i; ++j < n; )
{
if ( arr[j] < arr[i] )
{
swap( arr + i, arr + j );
}
}
}
}
Related
I'm a beginner in programing so please be understanding with my code.. I'm working on a problem set where I have to implement a selection sort using recursion. I feel like it should work but I get an error message and i can't figure out why.
the problem set consists in that I use a recursive function where i have to look for the largest number in an array, store it in the last position and sort the entire array using this method.
int array[n];
printf ("enter numbers: ");
for (i = 0; i < n; i++)
{
scanf ("%i", &array[i]);
}
selection_sort(n, array);
printf ("sorted numbers: ");
for (i = 0; i < n; i++)
{
printf ("%i", array[i]);
}
return 0;
here is the recursive function that i'd like to implement.
i used curpos to store the position of the largest number,
lastpos to store the location of the last element in the array,
and a tmp variable to store the largest number.
and this is the error message that i get.
.c:67:34: error: incompatible integer to pointer conversion passing 'int' to parameter of type 'int *'; take the address with & [-Werror,-Wint-conversion]
return selection_sort(n, array[n-1]);
^~~~~~~~~~
&
if (n <= 0)
{
return 1;
}
else
{
for (i = 0; i < n; i++)
{
if (tmp <= array[i]) //look for the largest number and update it into tmp
{
tmp = array[i];
curpos = array[i]; //remember the location of the current largestnumber
}
}
lastpos = array[n-1]; // save the last element into a variable before swap
array[n-1] = tmp; // put the largest number into the last element
curpos = lastpos; // put the last element before swap into the changed location.
return selection_sort(n, array[n-1]);
}
}
I hope you can give me a hand to understand the recursion better. thank you so much in advance.
The return value is a red herring. You don't use it so your function may as well be void.
if (n <= 0)
{
return 1;
}
The second thing to notice is that you can't pass an array to a function. You are passing a pointer to the beginning of the array. This is good, because otherwise you wouldn't be able to sort it.
else
{
for (i = 0; i < n; i++)
{
Right here is an issue. You haven't initialised tmp and curpos. You need to do that before the loop.
if (tmp <= array[i]) //look for the largest number and update it into tmp
{
tmp = array[i];
curpos = array[i]; //remember the location of the current largestnumber
}
}
lastpos = array[n-1]; // save the last element into a variable before swap
array[n-1] = tmp; // put the largest number into the last element
curpos = lastpos; // put the last element before swap into the changed location.
Finally, right here you have the right idea, but the wrong notation. You want to pass the same array, but 1 less element
return selection_sort(n, array[n-1]);
Should be:
return selection_sort(n-1, array);
}
The error message means that in this call
return selection_sort(n, array[n-1]);
you are passing an element of the array of the type int with the index n-1. But the function expects a pointer of the type int *.
Moreover the value of the first parameter is always the same and equal to n.
Also the return type of the function does not make a sense. The function should be declared with the return type void.
Also you need to swap two elements if within the array there is found an element that is greater than the last element.
The function can be declared and defined the following way
void selection_sort( int a[], size_t n )
{
if (!( n < 2 ))
{
size_t i = --n;
for (size_t j = n; j-- != 0; )
{
if (a[i] < a[j]) i = j;
}
if (i != n)
{
int tmp = a[i];
a[i] = a[n];
a[n] = tmp;
}
selection_sort( a, n );
}
}
Here is a demonstration program.
#include <stdio.h>
void selection_sort( int a[], size_t n )
{
if (!( n < 2 ))
{
size_t i = --n;
for (size_t j = n; j-- != 0; )
{
if (a[i] < a[j]) i = j;
}
if (i != n)
{
int tmp = a[i];
a[i] = a[n];
a[n] = tmp;
}
selection_sort( a, n );
}
}
int main( void )
{
int a[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
const size_t N = sizeof( a ) / sizeof( *a );
for (size_t i = 0; i < N; i++)
{
printf( "%d ", a[i] );
}
putchar( '\n' );
selection_sort( a, N );
for (size_t i = 0; i < N; i++)
{
printf( "%d ", a[i] );
}
putchar( '\n' );
}
The program output is
9 8 7 6 5 4 3 2 1 0
0 1 2 3 4 5 6 7 8 9
Hello everyone and thanks for your time.
For exercise, I wanted to write a program which copies all elements from an array to another array but without the duplicates. The only condition is that I cannot change the original array - so no sorting.
I tried making a function which checks if the current element of array1 is found in the array we copy to (array2). If no, we then copy the element to the second array and increase the size by one.
However, it does not work:
If I have
int array1[15] = {3,2,4,7,9,1,4,6,7,0,1,2,3,4,5};
int array2[15];
array2 should contain the following numbers: 3,2,4,7,9,1,6,0,5
But my output is as follows: 3,2,4,7,9,1,6
Here is the code:
#include <stdio.h>
#include <stdlib.h>
int already_exists(int array2[], int size_arr2, int element)
{
int i;
for(i=0; i<size_arr2; i++)
{
if(array2[i] == element)
return 1;
}
return 0;
}
int main()
{
int array1[15] = {3,2,4,7,9,1,4,6,7,0,1,2,3,4,5};
int array2[15];
int i;
int size_arr2=0;
for(i=0; i<9; i++)
{
int element = array1[i];
if(already_exists(array2, size_arr2, element) == 1)
continue;
else
{
array2[size_arr2] = element;
size_arr2++;
}
}
for(i=0; i<size_arr2; i++)
{
printf("%d, ", array2[i]);
}
return 0;
}
You have a typo in the for loop
for(i=0; i<9; i++)
The array array1 contains 15 elements. So the loop should look like
for ( i = 0; i < 15; i++ )
The reason of the error is that you are using "magic numbers" instead of named constants.
Nevertheless the program in whole is inefficient because the function already_exists is called for each element of the array array1. At least you could declare it as an inline function.
Moreover it should be declared like
int already_exists( const int array2[], size_t size_arr2, int element );
Instead of this function it is better to write a function that performs the full operation.
Here is a demonstrative program.
#include <stdio.h>
size_t copy_unique( const int a1[], size_t n1, int a2[] )
{
size_t n2 = 0;
for ( size_t i = 0; i < n1; i++ )
{
size_t j = 0;
while ( j < n2 && a2[j] != a1[i] ) j++;
if ( j == n2 ) a2[n2++] = a1[i];
}
return n2;
}
int main(void)
{
enum { N = 15 };
int array1[N] = { 3, 2, 4, 7, 9, 1, 4, 6, 7, 0, 1, 2, 3, 4, 5 };
int array2[N];
for ( size_t i = 0; i < N; i++ ) printf( "%d ", array1[i] );
putchar( '\n' );
size_t n2 = copy_unique( array1, N, array2 );
for ( size_t i = 0; i < n2; i++ ) printf( "%d ", array2[i] );
putchar( '\n' );
return 0;
}
Its output is
3 2 4 7 9 1 4 6 7 0 1 2 3 4 5
3 2 4 7 9 1 6 0 5
I am trying to do a selection sort where I am going through a list of integers, picking out the smallest number, and swapping it with a bigger number earlier in the list. This code is just practicing with a short string of 4 integers. What I am struggling with is getting through the whole list of integers to find the smallest number before moving on. I found that this works great as its own nested for loop, but then I can't 'remember' at which index that smallest number was at when trying to swap integers (this would be the line of code that is commented out, as it will not know what 'j' is). If I attempt doing this within the for loop then I prematurely swap the first integer that is smaller than the one I am swapping with before seeing if there are any other smaller integers. Any tips in the right direction would be much appreciated. Thank you!
int main (void)
{
int tmp;
int n = 4;
int values[] = {5,3,4,1};
for (int i=0; i < n; i++)
{
int minimum = values[i];
for (int j=1; j < n; j++)
{
if (values[j]<minimum)
{
minimum=values[j];
}
}
tmp = values[i];
values[i] = minimum;
//values[j] = tmp;
}
}
You need to add a variable minimumIndex which is the index of the minimum value. Set it to j when you update the value of minimum, and it will give you the index of the minimum at the end of the loop. Make also to initialize it with a correct value: Since mimimum is initialized to values[i], minimumIndex should be initialized to i.
Note also that you have a bug: You start the inner loop at j=1, but it should start with i or i+1 so that you skip over the elements which have already been placed.
Just keep the index of the element with the minimal value. For example
#include <stdio.h>
int main ( void )
{
int values[] = { 5, 3, 4, 1 };
size_t n = sizeof( values ) / sizeof( *values );
for ( size_t i = 0; i < n; i++ )
{
printf( "%d ", values[i] );
}
putchar( '\n' );
for ( size_t i = 0; i < n; i++ )
{
size_t minimum = i;
for ( size_t j = i + 1; j < n; j++ )
{
if ( values[j] < values[minimum] )
{
minimum = j;
}
}
if ( minimum != i )
{
int tmp = values[i];
values[i] = values[minimum];
values[minimum] = tmp;
}
}
for ( size_t i = 0; i < n; i++ )
{
printf( "%d ", values[i] );
}
putchar( '\n' );
}
Pay attention to that the index of the inner loop should start with the value i + 1.
for ( size_t j = i + 1; j < n; j++ )
^^^^^
#include <stdio.h>
void main()
{
int maj, count, n = 6;
int arr[] = {1, 2, 2, 2, 2, 3, 4};
for (int i = 0; i < n; i++) {
maj = arr[i];
count = 0;
for (int j = 9; j < n; j++) {
if (arr[j] == maj) count++;
}
if (count > n / 2) {
break; /* I think some problem is here ,if majority element not found then it takes last element as the majority element */
}
}
printf("%d", maj);
}
It is giving correct output if majority ellement is there but incorrect output if no majority element is there for example if array is {1,2,3,4} it is giving output as 4. please help!!
#include <stdio.h>
int main() {
int maj, count, n = 7; //n is size of arr
int arr[] = {1, 2, 2, 2, 2, 3, 4};
int isFound = 0; //0 -> false, 1 -> true
for (int i = 0; i < n; i++) {
maj = arr[i];
count = 1; //first elements is itself
isFound = 0; //by default we assume that no major elements is found
for (int j = i+1; j < n; j++) { //iterate from next elements onwards to right in array
if (arr[j] == maj) count++;
}
if (count > n / 2) {
isFound = 1;
break; //major elements found; no need to iterator further; just break the loop now
}
}
if(isFound) printf("%d ", maj);
else printf("no major element");
return 0;
}
For starters according to the C Standard function main without parameters shall be declared like
int main( void )
Try not to use magic numbers. Usually as in your program they are a reason for program bugs. For example you declared the array arr as having 7 elements however the variable n that should keep the number of elements in the array is initialized with the value 6. Another magic number 9 is used in the loop
for (int j = 9; j < n; j++) {
^^^
There is no need to write the outer loop that travers the whole array. Also the program does not report the case when the majority number does not exist in the array.
Using your approach with two loops the program can look the following way
#include <stdio.h>
int main( void )
{
int a[] = { 1, 2, 2, 2, 2, 3, 4 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t i = 0;
for ( ; i < ( N + 1 ) / 2; i++ )
{
size_t count = 1;
for ( size_t j = i + 1; count < N / 2 + 1 && j < N; j++ )
{
if ( a[i] == a[j] ) ++count;
}
if ( !( count < N / 2 + 1) ) break;
}
if ( i != ( N + 1 ) / 2 )
{
printf( "The majority is %d\n", a[i] );
}
else
{
puts( "There is no majority element" );
}
return 0;
}
Its output is
The majority is 2
I get a message when I try to run the program. Why?
Segmentation fault
my code:
#include <stdio.h>
void sort_array(int *arr, int s);
int main() {
int arrx[] = { 6, 3, 6, 8, 4, 2, 5, 7 };
sort_array(arrx, 8);
for (int r = 0; r < 8; r++) {
printf("index[%d] = %d\n", r, arrx[r]);
}
return(0);
}
sort_array(int *arr, int s) {
int i, x, temp_x, temp;
x = 0;
i = s-1;
while (x < s) {
temp_x = x;
while (i >= 0) {
if (arr[x] > arr[i]) {
temp = arr[x];
arr[x] = arr[i];
arr[i] = temp;
x++;
}
i++;
}
x = temp_x + 1;
i = x;
}
}
I think that the problem is in the if statement.
What do you think? Why does it happen? I think that I use in positive way with the pointer to the array.
Thank you!
This loop in your program
while (i >= 0) {
//...
i++;
}
does not make sense because i is increased unconditionly.
The program can look the following way
#include <stdio.h>
void bubble_sort( int a[], size_t n )
{
while ( !( n < 2 ) )
{
size_t i = 0, last = 1;
while ( ++i < n )
{
if ( a[i] < a[i-1] )
{
int tmp = a[i];
a[i] = a[i-1];
a[i-1] = tmp;
last = i;
}
}
n = last;
}
}
int main( void )
{
int a[] = { 6, 3, 6, 8, 4, 2, 5, 7 };
const size_t N = sizeof( a ) / sizeof( *a );
for ( size_t i = 0; i < N; i++ ) printf( "%d ", a[i] );
printf( "\n" );
bubble_sort( a, N );
for ( size_t i = 0; i < N; i++ ) printf( "%d ", a[i] );
printf( "\n" );
return 0;
}
The program output is
6 3 6 8 4 2 5 7
2 3 4 5 6 6 7 8
If you want that the sorting function had only one while loop then you can implement it the following way
void bubble_sort( int a[], size_t n )
{
size_t i = 0;
while ( ++i < n )
{
if ( a[i] < a[i-1] )
{
int tmp = a[i];
a[i] = a[i-1];
a[i-1] = tmp;
i = 0;
}
}
}
In your inner loop, you increment i beyond the size of the array. Your algorithm should require you to decrement i instead, but I am not sure this would be enough to fix the sorting algorithm.
You should first try to implement Bubble sort with a single while loop where you compare adjacent items and step back whenever you swap them.