Error in function for Selection-Sort - c

My code for selection-sort
#include <stdio.h>
void selection_sort(int a[], int n);
int main()
{
int size;
printf("Enter the size of array: ");
scanf("%d",&size);
int b[size],i = 0;
printf("Enter %d integers to be sorted: ",size);
while(i++ < size)
scanf("%d",&b[i]);
selection_sort(b, size);
printf("Sorted integers(by selection sort) are: ");
for(int i = 0; i < size; i++)
printf("%d",b[i]);
return 0;
}
void selection_sort(int a[], int n)
{
while(n >= 0 )
{
if(n == 0)
break;
else
{
int i = 0, c = 0;
int largest = a[0];
while(i++ < n)
if(largest < a[i])
{
c = i ;
largest = a[i];
}
int temp = a[--n];
a[n] = largest;
a[c] = temp;
selection_sort(a, n);
}
}
}
on sorting the array in ascending order
3 4 1 2
is giving weird output
2293388 4 3 0
I checked this many time but failed to remove the problem.
What should I do to work it properly?
Algorithm used :
1. search for largest element in the array.
2. Move largest element to the last position of array.
3. Call itself recursively to sort the first n -1 element of the array.
Please don't give any other solution otherwise I will get confused.

EDIT
Ah, I see what goes wrong. First of all, while (i++ < n) does not do exactly what you expect it to do. It checks if the condition i < n is true, then it increments i. However, it seems that after the conditional check, i is already incremented in the body. So for example,
while (i++ < n)
printf ("%d ", i);
will print out (with n=4):
1 2 3 4
So you first need to change that. Secondly, the outer while-loop is not at all necessary. Using one loop will suffice. Again, change the while loop in here to while (i < n) and increment i in the body. SO the final code will be:
#include <stdio.h>
void selection_sort(int a[], int n);
int main()
{
int size;
printf("Enter the size of array: ");
scanf("%d", &size);
int b[size], i = 0;
printf("Enter %d integers to be sorted: ", size);
while(i < size) {
scanf("%d", &b[i]);
i++;
}
selection_sort(b, size);
printf("Sorted integers(by selection sort) are: ");
i = 0;
for(i = 0; i < size; i++)
printf("%d ", b[i]);
printf ("\n");
return 0;
}
void selection_sort(int a[], int n)
{
if(n == 0)
return;
else
{
int i = 0, c = 0;
int largest = a[0];
while(i < n) {
if(largest < a[i])
{
c = i;
largest = a[i];
}
i++;
}
int temp = a[--n];
a[n] = a[c];
a[c] = temp;
selection_sort(a, n);
}
}
I tested this with your given input (3 4 1 2) and it prints out a sorted list: 1 2 3 4.

Whenever you see such weird big numbers, its usually an array out of bounds issue. Please take a small data-set, say 5-6 numbers, and walk through your program. I am sure you can fix it. Good luck!!

Related

Program to find prime numbers from the set of numbers of Fibonacci series in C

I want to find prime numbers from the Fibonacci series after printing them. First, I implemented the code for Fibonacci then added each element into an array. Then passed the array to a method to check for prime. Wanted to try it with an array. Displaying the series but not the prime numbers from the following code.
#include <stdio.h>
int fib()
{
int a=0,b=1, arr[20];
arr[0] = a;
arr[1] = b;
printf("%d, %d,",a, b );
int c=0;
for(int i=2; i<=20; i++)
{
c=a+b;
arr[i] = c;
printf("%d,",c);
a=b;
b=c;
}
checkPrime(arr);
}
void checkPrime(int a[])
{
int i, count;
for(i=0; i<sizeof(a); i++)
{
count=0;
for(int j=2; j<=a[i]/2 ; j++)
{
if(a[i]%2==0)
count++;
}
if(count>1)
printf("%d is a Prime", a[i]);
}
}
int main()
{
fib();
}
Output of the code
0, 1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,
8 is a Prime
You have certain bugs in your implementation.
In fib function you iterate until i <= 20 but your arr have length 20 therefore your loop will go out of bounds of array. You should iterate until i < 20 or increase length of your array.
In checkPrime function you iterate until i < sizeof(a). But sizeof function doesn't return size of your array. It returns size of type of variable that you pass to it therefore it will return sizeof(int*) which = 8 (in case you 64 bit machine but I guess you have). To fix this bug you should pass length of your array in checkPrime function and use it.
You don't reset the count variable after j loop.
checkPrime function doesn't check if the number is prime. You have wrong expression in your nested loop. To check if number N is prime you should check if there any divisor of N that at least less than sqrt(N). Your expression is wrong.
Considering the adjustments above I suggest the next solution:
void checkPrime(int a[], size_t a_len) {
int i, count;
for (i = 1; i < a_len; i++) {
count = 0;
for (int j = 2; j <= sqrt((double)a[i]); j++) {
if (a[i] % j == 0) {
count++;
break;
}
}
if (count == 0) {
printf("%d is a Prime\n", a[i]);
} else {
count = 0;
}
}
}
int fib() {
size_t arr_size = 21;
int a = 0, b = 1, arr[arr_size];
arr[0] = a;
arr[1] = b;
printf("%d, %d, ", a, b);
int c = 0;
for (int i = 2; i < arr_size; i++) {
c = a + b;
arr[i] = c;
if (i == arr_size - 1)
printf("%d ", c);
else
printf("%d, ", c);
a = b;
b = c;
}
printf("\n");
checkPrime(arr, arr_size);
}

Facing Runtime error while Solving finding and counting duplicates in c

Can someone please help me i am facing runtime error while solving this problem.
I have first defined the integers and then used scanf to take the input.
Then i check whether the 2 consecutive elements of array are equal are not.
if they are equal i equate j variable to i+1 and so that it can traverse and find if same duplicate elements are side by side (eg- 15 15 15).
I increment the j element till a[j] is equal to a[i].
Then using i try to print the number with the number of occurences of it which is j-i and then assign i with vakue of j-1.
#include <stdio.h>
int main()
{
int n,j=0,i;
scanf("%d",&n);
int a[n];
for (i = 0; i < n; ++i) {
scanf("%d",&a[i]);
}
for (i = 0; i < n - 1; ++i)
{
if(a[i]==a[i+1])
{
j=i+1;
while(j<n && a[i]==a[j])
{
j++;
}
printf("%d is appearing %d times\n",a[i],j-i);
}
i=j-1;
}
return 0;
}
The input array needs to be sorted first to count duplicated, the loop logic needs to be fixed to reassign the index i.
A fixed code might like this:
#include <stdio.h>
#include <stdlib.h>
static int cmp_intp(const void *p1, const void *p2) {
return *(const int *)p1 > *(const int *)p2;
}
int main() {
int n, j = 0, i;
scanf("%d", &n);
int a[n];
for (i = 0; i < n; ++i) {
scanf("%d", &a[i]);
}
qsort(a, n, sizeof(a[0]), cmp_intp);
for (i = 0; i < n;) {
if (i < n - 1 && a[i] == a[i + 1]) {
j = i + 1;
while (j < n && a[i] == a[j]) {
j++;
}
printf("%d is appearing %d times\n", a[i], j - i);
i = j;
} else {
++i;
}
}
return 0;
}
The problem is created by the line,
i=j-1;
in the case when two consecutive elements are not equal.
move it within the if condition.

Reversing array elements in C programming

I am new to C and I have a problem. I need to reverse the elements of arrays in the following program. Can I get a very simple explanation of what I am doing wrong and how I could go on about fixing it?
Here's the output I get:
Enter number 0: 0
Enter number 1: 1
Enter number 2: 2
Enter number 3: 3
Enter number 4: 4
Enter number 5: 5
Enter number 6: 6
Enter number 7: 7
Element 0 is: 7
Element 1 is: 6
Element 2 is: 5
Element 3 is: 4
Element 4 is: 4
Element 5 is: 5
Element 6 is: 6
Element 7 is: 7
My code:
#include <stdio.h>
void reverse(int a[], int i)
{
int j=7,b;
for (i=0; i<=7; i++)
{
b=a[i];
a[i]=a[j];
a[j]=b;
printf("Element %d is: %d\n", i,a[i]);
j--;
}
}
int main(void)
{
int a[8];
int i;
for(i=0;i<=7;i++)
{
printf("Enter number %d: ",i);
scanf("%d", &a[i]);
}
reverse(a, 8);
return 0;
}
To avoid being misled, write the output after the reversal, not during it:
#include <stdio.h>
void reverse(int a[], int i)
{
int j = 7, b;
for (i = 0; i <= 7; i++)
{
b = a[i];
a[i] = a[j];
a[j] = b;
j--;
}
}
int main(void)
{
int a[8];
int i;
for (i = 0; i <= 7; i++)
{
printf("Enter number %d: ",i);
scanf("%d", &a[i]);
}
reverse(a, 8);
for (i = 0; i <= 7; i++)
{
printf("Element %d is: %d\n", i, a[i]);
}
return 0;
}
Now you’ll notice the array isn’t changing at all. That’s because you’re swapping every element in the array twice: once to its reversed position, then back to its original position. To fix this, only loop over the first half the array, i.e. while i < 4.
It was probably also intended to make the second argument to reverse the length, so you should make use of that instead of hard-coding 7 or 4:
void reverse(int a[], int length)
{
int i, j = length - 1, b;
for (i = 0; i < length / 2; i++)
{
b = a[i];
a[i] = a[j];
a[j] = b;
j--;
}
}
You could also copy over the array in a new one:
#include <stdio.h>
void reverse(int a[], int i)
{
int b[i];
int j;
for(j=0; j<i; j++){
b[j] = a[i-1-j];
printf("Element %d is: %d\n", j, b[j]);
}
}
int main(void)
{
int a[8];
int i;
for(i=0;i<=7;i++)
{
printf("Enter number %d: ",i);
scanf("%d", &a[i]);
}
reverse(a, 8);
return 0;
}
What you want to do it move through only half of the length of your array else you're reversing the array twice.
void reverse(int a[], int len)
{
int i;
int j=len-1,b;
for(i=0;i<len/2;i++)
{
b=a[i];
a[i]=a[j];
a[j]=b;
j--;
}
for(i = 0; i < len; i++) {
printf("Element %d is: %d\n", i,a[i]);
}
}
The Principe is simple. just stand at the middle of the table and reverse the elements as follow. so pose n is lent of the table. then the last element is n-1.
so you ave to reverse position t[0] and t[n-2]
reverse t[1] and t[n-3] and so on...
stop when you rich the middle of the table. try to code your self is better than for me giving you the code.
hope it helped.

Swapping largest and smallest numbers in C

I want to write a program that reads 10 int values from the user and swaps the largest and smallest numbers on the first and second values, then the rest of the numbers should be in the order.
Please check the code and help me what the wrong is.
For instance:
1
9
4
5
6
7
8
2
4
5
New order should be 9 1 4 5 6 7 8 2 4 5
#include <stdio.h>
int main() {
int a[10],i,min,max=0,pos=0;
printf("Please enter 10 int values :\n");
do{
scanf("%d", &a[pos++]);
} while (pos<10);
for (i=0; i<10;i++) {
printf("%i\n",a[i]);
if (max<a[i])
{
max=a[i];
}
if (min>a[i])
{
min=a[i];
}
for (i=0;i<10;i++) {
if (a[i]==max)
a[i]=max;
if (a[i] == min) a[i] = min;
}
printf("The new order is : %d %d %d ", max, min, ...);
return 0;
}
EDIT:
It is the new form
#include <stdio.h>
int main() {
int a[10],i,pos,temp,min = 0,max = 0;
printf("Please enter 10 int values :\n");
do {
scanf("%d", &a[pos++]);
} while (pos < 10);
for ( =1; i<10;i++) {
if (a[i]>a[max])
{
max=i;
}
if (a[i]<a[min])
{
min=i;
}
}
temp=a[max];
a[max]=a[min];
a[min]=temp;
printf("%d %d",a[max],a[min]);
for (i=0;i<10;i++){
if ((i != min) && (i != max)) {
printf("%d ", a[i]);
}
}
printf("\n");
return 0;
}
As others have noted, your code does not properly identify the maximum and minimum values in the array because you are writing min and max back into the array instead of the other way around.
Since you want to swap these values, what you actually want are the indices of the min and max values of the array, and swap those.
It is best to break this code into functions instead of having everything in main. Here is a solution that will do what you want:
#include <stdio.h>
int indexofmax(int *data, int len)
{
int max = 0;
int i;
for(i = 0; i < len; i++)
{
if(data[i]>data[max]) max = i;
}
return max;
}
int indexofmin(int *data, int len)
{
int min = 0;
int i;
for(i = 0; i < len; i++)
{
if(data[i]<data[min]) min = i;
}
return min;
}
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
int main()
{
// user enters in 10 ints...
int max = indexofmax(a, 10);
int min = indexofmin(a, 10);
int i;
swap(&a[min], &a[max]);
for(i = 0; i < 10; i++)
{
printf("%d ", a[i]);
}
return 0;
}
This initialization min=0,max=0 is not right.
Instead have min = INT_MAX and max = INT_MIN.
By setting min=0, you would never get the lowest number in the array if it is greater than 0.
Similarly by setting max=0, you would never get the greatest number in the array if it is lower than 0.
You are gaining nothing by this code:
for(i=0;i<10;i++)
{ if(a[i]==max) a[i]=max;
if(a[i]==min) a[i]=min; }
It is evident that this loop
for(i=0;i<10;i++)
{ if(a[i]==max) a[i]=max;
if(a[i]==min) a[i]=min; }
does not make sense.
Moreover variable min is not initialized while variable max is initialized incorrectly.
int a[10],i,min,max=0,pos=0;
For example the array can contain all negative elements. In this case you will get incorrect value of the maximum equal to 0.
And I do not see where the elements are moved to the right to place the maximum and the minimum to the first two positions of the array.
If I have understood correctly then what you need is something like the following. To move the elements you could use standard function memmove declared in header <string.h>. However it seems you are learning loops.
#include <stdio.h>
#define N 10
int main( void )
{
int a[N] = { 4, 5, 9, 6, 7, 1, 8, 2, 4, 5 };
for (size_t i = 0; i < N; i++) printf("%d ", a[i]);
printf("\n");
size_t min = 0;
size_t max = 0;
for (size_t i = 1; i < N; i++)
{
if (a[max] < a[i])
{
max = i;
}
else if (a[i] < a[min])
{
min = i;
}
}
if (max != min)
{
int min_value = a[min];
int max_value = a[max];
size_t j = N;
for (size_t i = N; i != 0; --i)
{
if (i - 1 != min && i - 1 != max)
{
if (i != j)
{
a[j - 1] = a[i - 1];
}
--j;
}
}
a[--j] = min_value;
a[--j] = max_value;
}
for (size_t i = 0; i < N; i++) printf("%d ", a[i]);
printf("\n");
}
The program output is
4 5 9 6 7 1 8 2 4 5
9 1 4 5 6 7 8 2 4 5
You're not actually altering the array.
In the second loop, you say "if the current element is the max, set it to the max". In other words, set it to its current value. Similarly for the min.
What you want is to swap those assignments.
if(a[i]==max) a[i]=min;
if(a[i]==min) a[i]=max;
Also, your initial values for min and max are no good. min is unitialized, so its initial value is undefined. You should initialize min to a very large value, and similarly max should be initialized to a very small (i.e. large negative) value.
A better way to do this would be to keep track of the index of the largest and smallest values. These you can initialize to 0. Then you can check a[i] > a[max] and a[i] < a[min]. Then you print the values at indexes min and max, then loop through the list and print the others.
int i, temp, min=0, max=0;
for (i=1; i<10; i++) {
if (a[i] > a[max]) max = i;
if (a[i] < a[min]) min = i;
}
printf("%d %d ", a[max], a[min]);
for (i=0; i<10; i++) {
if ((i != min) && (i != max)) {
printf("%d ", a[i]);
}
}
printf("\n");
Just keep it nice and simple, like this:
#include <stdio.h>
#include <stdlib.h>
#define MAXNUM 10
int find_biggest(int A[], size_t n);
int find_smallest(int A[], size_t n);
void print_array(int A[], size_t n);
void int_swap(int *a, int *b);
int
main(void) {
int array[MAXNUM], i, smallest, biggest;
printf("Please enter 10 int values:\n");
for (i = 0; i < MAXNUM; i++) {
if (scanf("%d", &array[i]) != 1) {
printf("invalid input\n");
exit(EXIT_FAILURE);
}
}
printf("Before: ");
print_array(array, MAXNUM);
smallest = find_smallest(array, MAXNUM);
biggest = find_biggest(array, MAXNUM);
int_swap(&array[smallest], &array[biggest]);
printf("After: ");
print_array(array, MAXNUM);
return 0;
}
int
find_biggest(int A[], size_t n) {
int biggest, i, idx_loc;
biggest = A[0];
idx_loc = 0;
for (i = 1; i < n; i++) {
if (A[i] > biggest) {
biggest = A[i];
idx_loc = i;
}
}
return idx_loc;
}
int
find_smallest(int A[], size_t n) {
int smallest, i, idx_loc;
smallest = A[0];
idx_loc = 0;
for (i = 1; i < n; i++) {
if (A[i] < smallest) {
smallest = A[i];
idx_loc = i;
}
}
return idx_loc;
}
void
print_array(int A[], size_t n) {
int i;
for (i = 0; i < n; i++) {
printf("%d ", A[i]);
}
printf("\n");
}
void
int_swap(int *a, int *b) {
int temp;
temp = *a;
*a = *b;
*b = temp;
}

Comparing arrays in a function

My function countCopies doesn't work even though it gets the right inputs. All it should do is taking an array of integers as an input and then searching through this array for duplicates of the second input x.
int main() {
char intArray[100]; //The integer array can only hold 100 integers
int i, x, j;
printf("Please enter a couple of integers and when you're done enter end. ");
i = 0;
while (scanf("%d", &intArray[i++]) == 1)
/*empty loop*/;
scanf("%*s");
printf("Enter x:");
scanf("%d", &x);
printf("Copies = %d\n", countCopies(intArray, i, x));
}
int countCopies(int a[], int n, int x) {
int count = 0;
int j = 0;
for (j = 0; j < n - 1; j++) {
if (a[j] == x) {
count++;
}
}
return count;
}
The for loop is incorrect: you should change the test to j < n.
The idiomatic for loop in C: for (j = 0; j < n; j++) ... iterates exactly n times, j taking values 0 to n-1 inclusively, which are correspond to exactly all valid positions in an array of n elements.
Note that the array has the wrong element type: it should be int, not char. You should also check for array bounds in the first loop and for conversion success of the last scanf.
Here is a corrected version:
#include <stdio.h>
int countCopies(int a[], int n, int x);
int main(void) {
int intArray[100]; //The integer array can only hold 100 integers
int i, x;
printf("Please enter a series of integers, end the list with the word end.\n");
for (i = 0; i < sizeof(intArray) / sizeof(*intArray); i++) {
if (scanf("%d", &intArray[i]) != 1)
break;
}
if (scanf("%d", &x) == 1) {
printf("too many numbers\n");
return 1;
}
scanf("%*s"); /* skip the end word. Note that any word is OK */
printf("Enter x:");
if (scanf("%d", &x) == 1) {
printf("Copies = %d\n", countCopies(intArray, i, x));
}
return 0;
}
int countCopies(int a[], int n, int x) {
int j, count = 0;
for (j = 0; j < n; j++) {
if (a[j] == x) {
count++;
}
}
return count;
}
To expand on chqrlie's answer,
The code for (i = 0; i < n; i++) {/* do stuff */} executes in the following order:
The variable i is set to zero.
The conditional i < n is tested. If true, the code in /* do stuff */ is executed, otherwise, the loop is exited.
The increment i++ is applied.
Go back to 2.
That means that on the loop iteration when i gets incremented to n, the for loop breaks before the code inside the loop gets executed, so if you're accessing an array with n elements, the last element that gets accessed has the index n - 1. Hence the C loop paradigm that chqrlie mentioned.

Resources