Sorting array based on index of minimum value? - c

I'm currently trying to learn C, and the exercise I found online has me creating a function that returns the index of the smallest value in an array. This is my function:
int return_index_of_minimum(int A[10], int i, int j){
int minimum_value = A[i];
int index_to_return = 0;
for (int index = i; index < j; index++){
if (A[index] < minimum_value){
minimum_value = A[index];
index_to_return = index;
}
}
return index_to_return;
}
i and j are the lower and upper bound numbers the function should look in. For example, if i is 4 and j is 8, that means the function will return the index of the smallest value between indices 4 and 8.
Here is my main function:
#include <stdio.h>
int main(){
int numbers[10];
int user_input = 0;
for (int i = 0; i < 10; i++){
printf("Please enter a number: ");
scanf_s("%d", &user_input);
numbers[i] = user_input;
}
for (int i = 0; i < 10; i++){
int index_of_min_value = return_index_of_minimum(numbers, i, 10);
int old_num = numbers[index_of_min_value];
int new_num = numbers[i];
numbers[index_of_min_value] = new_num;
new_array[i] = old_num;
}
for (int i = 0; i < 10; i++){
printf("%d\n", new_array[i]);
}
}
The user would first enter a bunch of numbers and that would populate the array with the user's values. The idea is to use return_index_of_minimum to return the index of the smallest item in an array, and then set that equal to numbers[0] with a for loop, and then numbers[1], and then so on. old_num is the lowest number in the array, at its previous index. Here, I'm trying to swap that minimum value with whatever is at numbers[i] However, when I'm done sorting through the entire array, and am printing it out, I see that 10 (when the user enters 1-10 randomly for values) is at index 0, and then the rest of the numbers are in order. Does anybody see what is wrong here?

Here is a fix:
int return_index_of_minimum(int A[10], int i, int j){
int minimum_value = A[i];
int index_to_return = i;
...
}
Unfortunately this code doesn't have protection of invalid arguments, but otherwise this is an answer you've been looking for.
The reason is in call index_of_minimum(a, 9, 10): the loop performs only one iteration for index = 9, and because the minimum value is already initialized to value a[9], the index_to_return is not updated due to condition check.
This is a different approach that doesn't have same issue:
int return_index_of_minimum(int A[10], int i, int j){
/* assuming i < j */
int minimum_value = A[i];
int index_to_return = i; /* First element is a candidate */
for (int index = i + 1; index < j; index++){
/* Iterate from second element */
if (A[index] < minimum_value){
minimum_value = A[index];
index_to_return = index;
}
}
return index_to_return;
}

I believe there is an error in your return_index_of_minimum function.
int index_to_return = 0;
The problem lies I think here as the value of index_to_return will stay 0 if you call return_index_of_minimum(numbers, 5, 10); and that numbers[5] if the actual minimum.
However why not use a simple bubble-sort like the one implemented here
/*
* C program to sort N numbers in ascending order using Bubble sort
* and print both the given and the sorted array
*/
#include <stdio.h>
#define MAXSIZE 10
int main(void)
{
int array[MAXSIZE];
int i, j, num, temp;
printf("Enter the value of num \n");
scanf("%d", &num);
printf("Enter the elements one by one \n");
for (i = 0; i < num; i++)
{
scanf("%d", &array[i]);
}
printf("Input array is \n");
for (i = 0; i < num; i++)
{
printf("%d\n", array[i]);
}
/* Bubble sorting begins */
for (i = 0; i < num; i++)
{
for (j = 0; j < (num - i - 1); j++)
{
if (array[j] > array[j + 1])
{
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
printf("Sorted array is...\n");
for (i = 0; i < num; i++)
{
printf("%d\n", array[i]);
}
}

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);
}

Sorting an array with duplicate values without modifying the elements, without using secondary array or without using any inbuilt function

So as the question says i am just trying to sort an array with duplicate values.
The array is sorted properly but problem arises when a duplicate value is given to the array
O/P:without duplicate
Enter the size of the array : 5
Enter the 5 elements
7 3 4 8 1
After sorting: 1 3 4 7 8
Original array value 7 3 4 8 1
O/P: with duplicates
5 3 1 1 4
After sorting: 1 3 4 1 3
Original array value 5 3 1 1 4
#include <stdio.h>
void print_sort(int *arr, int size) //function definition
{
int i, j, k, temp, largest = arr[0], smallest = arr[0];
for( i = 1 ; i < size ; i++ )
{
if(arr[i] > largest)
{
largest = arr[i];
}
if(arr[i] < smallest)
{
smallest = arr[i];
}
}
printf("After sorting: ");
for(i = 0; i < size; i++)
{
temp = largest;
printf("%d ", smallest);
for(k = i + 1; k < size; k++)
{
if(arr[i] == arr[k])
{
smallest = arr[i];
break;
}
for(j = 0; j < size; j++)
{
if(arr[j] > smallest && arr[j] < temp)
{
temp = arr[j];
}
}
smallest = temp;
}
}
printf("\n");
printf("Original array value ");
for( i = 0 ; i < size ; i++ )
{
printf("%d ", arr[i]);
}
}
int main()
{
int size, i;
printf("Enter the size of the array : ");
scanf("%d", &size);
int arr[size];
printf("Enter the %d elements\n",size);
for (i = 0; i < size; i++)
{
scanf("%d", &arr[i]);
}
print_sort(arr, size);
}
I understand that it is a specific exercise (homework ?), with no possibility to modify the array not to use an additional array.
This implies that classical sorting algorithms cannot work.
Iteratively searching for the minimum is a possible solution, even if not efficient O(n^2).
To cope with duplicates, it it necessary not only to memorize the current minimum, but also its position.
This is a possible implementation.
#include <stdio.h>
#include <stdlib.h>
void print_sort(int *arr, int size) //function definition
{
int i, j, k, largest = arr[0], smallest = arr[0];
int i_smallest = 0;
for (i = 1; i < size; i++ ) {
if (arr[i] > largest) {
largest = arr[i];
}
if(arr[i] < smallest) {
smallest = arr[i];
i_smallest = i;
}
}
printf("After sorting: ");
for (i = 0; i < size; i++) {
int temp = largest + 1;
int i_temp = -1;
printf("%d ", smallest);
if (i == size-1) break;
for (k = 0; k < size; k++) {
if (arr[k] < smallest) continue;
if (arr[k] == smallest) {
if (k <= i_smallest) continue;
i_temp = k;
temp = smallest;
break;
}
if (arr[k] < temp) {
temp = arr[k];
i_temp = k;
}
}
smallest = temp;
i_smallest = i_temp;
}
printf("\n");
printf("Original array value ");
for( i = 0 ; i < size ; i++ )
{
printf("%d ",arr[i]);
}
}
int main(void) {
int size, i;
printf("Enter the size of the array : ");
if (scanf("%d", &size) != 1) exit(1);
int arr[size];
printf("Enter the %d elements\n",size);
for (i = 0; i < size; i++) {
if (scanf("%d", &arr[i]) != 1) exit(1);
}
print_sort(arr, size);
return 0;
}
Maybe it is easier to insert each read value directly into the sorted Array. So you don't have to sort the array afterwards.
If you want to do it this way, geeksforgeeks.org has nice examples also for C which I already used (https://www.geeksforgeeks.org/search-insert-and-delete-in-a-sorted-array/).
// C program to implement insert operation in
// an sorted array.
#include <stdio.h>
// Inserts a key in arr[] of given capacity. n is current
// size of arr[]. This function returns n+1 if insertion
// is successful, else n.
int insertSorted(int arr[], int n, int key, int capacity)
{
// Cannot insert more elements if n is already
// more than or equal to capacity
if (n >= capacity)
return n;
int i;
for (i = n - 1; (i >= 0 && arr[i] > key); i--)
arr[i + 1] = arr[i];
arr[i + 1] = key;
return (n + 1);
}
/* Driver program to test above function */
int main()
{
int arr[20] = { 12, 16, 20, 40, 50, 70 };
int capacity = sizeof(arr) / sizeof(arr[0]);
int n = 6;
int i, key = 26;
printf("\nBefore Insertion: ");
for (i = 0; i < n; i++)
printf("%d ", arr[i]);
// Inserting key
n = insertSorted(arr, n, key, capacity);
printf("\nAfter Insertion: ");
for (i = 0; i < n; i++)
printf("%d ", arr[i]);
return 0;
}

Why is my code producing a segmentation fault?

So im working on this program that is supposed to take the pointer to an array and the array’s size (number of elements in the array)
as arguments, finds the place the index of the outlier, fixes the array in place (that is puts the outlier to a
place it is supposed to be), and returns the old index where the outlier was found. i finished my code but for some reason, somewhere in my main function its telling me there is a segmentation fault, i know its in my main function because it compiled and ran fine when it was just the original code. heres the code;
#include <stdio.h>
long long int fix_sorted_array(double* arr, unsigned long n)
{
double temp;
int i, j;
for ( i = 0; i < n - 1; i ++)
{
if (arr[i] > arr[i + 1])
{
for ( j = i + 1; j > 0; j --)
{
if (arr[j] < arr[j-1])
{
temp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = temp;
}
}
return i + 1;
}
}
return -1;
}
int main()
{
int n;
int j;//declared variables
double arr[n];
printf("Enter elements of array : \n");
for ( int i = 0; i < n; i ++)
{
scanf("%lf", &arr[i]);
}
printf("Return index : %lld\n",fix_sorted_array (&arr[n], n));
printf("Array after : \n");
for ( j = 0; j < n; j ++)
{
printf("%.2lf", arr[j]);
}
}
You're passing an address outside the array to the function in this line:
printf("Return index : %lld\n",fix_sorted_array (&arr[n], n));
You want to pass the address of the start of the array, not the end, so it should be:
printf("Return index : %lld\n",fix_sorted_array (arr, n));
You also need to initialize n before you declare the array.
printf("How many numbers? ");
scanf("%d", &n);
double arr[n];
You have never accepted the value of n. Below code might help.
#include <stdio.h>
long long int fix_sorted_array(double* arr, unsigned long n)
{
double temp;
int i, j;
for ( i = 0; i < n - 1; i ++)
{
if (arr[i] > arr[i + 1])
{
for ( j = i + 1; j > 0; j --)
{
if (arr[j] < arr[j-1])
{
temp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = temp;
}
}
return i + 1;
}
}
return -1;
}
int main()
{
int n;
int j;//declared variables
printf("Enter the number of elements in arrays");
scanf("%d",&n); // initialize the values of n
double arr[n];
printf("Enter elements of array : \n");
for ( int i = 0; i < n; i ++)
{
scanf("%lf", &arr[i]);
}
printf("Return index : %lld\n",fix_sorted_array (&arr[0], n)); // Also pass the value of starting index in array i.e. `arr[0]`
printf("Array after : \n");
for ( j = 0; j < n; j ++)
{
printf("%.2lf", arr[j]);
}
}

Insert a number between every element in my array in C

I am completely stuck when it comes to the C language and inserting into arrays. I have my code below and to explain it say the user wants an array of 3. So the user inputs 4 3 2 into array a1[n]. I need array a2[] to output the same numbers but a zero between each. The end result would be 4 0 3 0 2 0 when a2[] is output. How would I get a zero between every other element?
#include <stdio.h>
int main() {
int n = 0;
int number = 0;
int a1[n];
int a2[2 * n];
printf("Enter the length of the array: ");
scanf("%d", &n);
printf("Enter the elements of the array: ");
for(i = 0; i < n; i++){ //adds values to first array
scanf("%d",&number);
a1[i] = number; }
for(i = 0; i < n; i++){ //copies and sets the arrays the same
a2[i] = a1[i]; }
Assuming your arrays are correctly defined and initialized (statically or dynamically), it is just a matter of properly counting during copying:
for(int i = 0; i < n; i++){
a2[i+i] = a1[i];
if(i < n-1) a2[i+i+1] = 0;
}
int n = 0;
int number = 0;
int a1[n];
int a2[2 * n];
Congratulations, now a1 and a2 are arrays of zero length. Even if you change n later, this doesn't affect the lengths of arrays. In C, you cannot make an array longer or shorter.
Try int* and calloc instead.
First of all, you can't create stack-allocated or static array with runtime-defined size.
int a[N]; // N should be determined during compilation
You should use heap-alloceted or dynamic array:
int *a;
a = (int *)malloc(2 * n, sizeof(int)); // n may be defined by user input
There is no way to resize array without moving it to another place, and you can just create a new one (larger then first) and fill it with source numbers and zeroes:
#include <stdio.h>
int main() {
int n = 0;
printf("Enter the length of the array: ");
scanf("%d", &n);
int *a1 = (int *)malloc(n, sizeof(int));
int *a2 = (int *)malloc(n * 2, sizeof(int));
printf("Enter the elements of the array: ");
int i, number;
for(i = 0; i < n; i++){ //adds values to first array
scanf("%d",&number);
a1[i] = number;
}
for(i = 0; i < n; i++){ //copies and sets the arrays the same
a2[i * 2] = a1[i];
a2[i * 2 + 1] = 0;
}
for(i = 0; i < n * 2; ++i){
printf("%d ", a2[i]);
}
}
Add below code in last loop.
for ( j=0, i=0; i <= n; i++ ) {
a2[j++] = a1[i];
a2[j++] = 0;
}
You have to multiply the indices by 2:
for(i = 0; i < n; ++i) { //copies and sets the arrays the same
a2[2 * i] = a1[i];
}
Not only that, odd-indexed elements of a2 should be set to zero. You can do it explicitly in loop:
for(i = 0; i < n; ++i) a2[2 * i + 1] = 0;
But simpler is to first initialize the array with zeroes:
int a2[2 * n] = {0};
Even-numbered elements will later be overwritten with elements of a1.

array counting sort segmentation fault

Hello i am trying to use counting sort to sort numbers that i read from a file. this is my code:
void CountingSort(int array[], int k, int n)
{
int i, j;
int B[100], C[1000];
for (i = 0; i <= k; i++)
{
C[i] = 0;
}
for (j = 1; j <= n; j++)
{
C[array[j]] = C[array[j]] + 1;
}
for (i = 1; i <= k; i++)
{
C[i] = C[i] + C[i-1];
}
for (j = 1; j <= n; j++)
{
B[C[array[j]]] = array[j];
C[array[j]] = C[array[j]] - 1;
}
printf("The Sorted array is : ");
for (i = 1; i <= n; i++)
{
printf("%d ", B[i]);
}
}
void max(int array[],int *k,int n){
int i;
printf("n je %d\n",n);
for (i = 0; i < n; i++)
{
if (array[i] > *k) {
*k = array[i];
}
}
}
int main(int brArg,char *arg[])
{
FILE *ulaz;
ulaz = fopen(arg[1], "r");
int array[100];
int i=0,j,k=0,n,x,z;
while(fscanf(ulaz, "%d", &array[i])!=EOF)i++;
fclose(ulaz);
n=i;
max(array,&k,n);
printf("Max je %d\n",k);
CountingSort(array,k,n);
return 0;
}
i have no errors but when i start my program i get Segmentation fault error. pls help! (dont read this bot is asking me to write some more details but i have none so i just write some random words so i can post my question and hopefully get an answer)
The problem is that your implementation of the counting sort is incorrect: it uses arrays as if they were one-based, while in C they are zero-based.
After carefully going through your loops and fixing all situations where you use a for loop that goes 1..k, inclusive, instead of the correct 0..k-1, the code starts to work fine:
int i, j;
int B[100], C[1000];
for (i = 0; i <= k; i++){
C[i] = 0;
}
for (j = 0; j < n; j++){
C[array[j]]++;
}
for (i = 1; i <= k; i++){
C[i] += C[i-1];
}
for (j = 0; j < n; j++) {
B[--C[array[j]]] = array[j];
}
printf("The Sorted array is : ");
for (i = 0; i < n; i++) {
printf("%d ", B[i]);
}
Demo.
Note: I modified some of the operations to use C-style compound assignments and increments/decrements, e.g. C[array[j]]++ in place of C[array[j]] = C[array[j]] + 1 etc.
The problem most likely is here
int B[100], C[1000]; // C has space for numbers up to 999
...
for (i = 1; i <= k; i++)
C[i] = C[i] + C[i-1]; // adding up till C[k] == sum(array)
for (j = 0; j < n; j++)
B[C[array[j]]] = array[j]; // B has space up to 99, but C[k] is sum(array)
so you're reserving space for C for a highest value of 999 but in B you're assuming that the sum of all input values is less than 100...
the resolution of your problem is to first probe the input array and get the maximum and the sum of all input values (and minimum if the range may be negative) and allocate space accordingly
edit: you probably meant j < n and not j <= n
Adding to dasblinkenlight's spot-on answer:
Is your input data guaranteed to be in the range [0, 999]? If it isn't, it's obvious that segmentation faults can and will occur. Assume that the maximum value of array is 1000. C is declared as
int C[1000];
which means that C's valid indices are 0, 1, 2, ... 999. But, at some point, you will have the following:
C[array[j]] = ... /* whatever */
where array[j] > 999 so you will be attempting an out-of-bounds memory access. The solution is simple: probe array for its maximum value and use dynamic memory allocation via malloc:
/* assuming k is the maximum value */
int * C = malloc((k + 1) * sizeof(int));
Note: an alternative to this, which would also nullify the need for an initialization loop to make all elements of C equal to 0, would be to use calloc, which dynamically allocates memory set to 0.
// allocate C with elements set to 0
int * C = calloc(k + 1, sizeof(int);
Another important factor is the range of your running indices: you seem to have forgotten that arrays in C are indexed starting from 0. To traverse an array of length K, you would do:
for (i = 0; i < K; ++i)
{
processArray(array[i]);
}
instead of
for (i = 1; i <= K; ++i)
{
processArray(array[i]);
}

Resources