Array sorting based on another array order - c

I am new to C and am having some issues with this code.
I need to split an array into two different arrays and sort the second array in whatever order the first one is.
Any thought please?
Below is where I got so far:
#include <stdio.h>
void main ()
{
int currentN;
int i, n;
int array[20];
printf("Enter the value of n\n");
scanf("%d", &n);
if (n%2 !=0)
{
printf("sequence would not be equ. please enter Odd \n");
printf("Please Enter even number\n");
scanf("%d", &n);
}
//add
printf("enter the numbers\n");
for (i = 0; i < n; ++i)
{
scanf("%d", &array[i]);
// scanf("%d", &currentN);
// seq[i]= currentN;
}
n++;
//add
int *firstHalf = malloc(n/2 * sizeof(int));
if (!firstHalf)
{
/* handle error */
}
int *secondHalf = malloc(n/2 * sizeof(int));
if (!secondHalf)
{
/* handle error */
}
memcpy(firstHalf, array, n/2 * sizeof(int));
memcpy(secondHalf, array + n/2, n/2 * sizeof(int));
for (i = 0; i < n/2; i++)
{
printf( "%d\t", firstHalf[i]);
//printf( "%d\n", secondHalf[i]);
//printf( "\n************************");
}
printf("\n*********************\n");
for (i = 0; i < n/2; i++)
{
printf( "%d\t", secondHalf[i]);
}
}

One way to get what you need:
Create a struct that has two members.
Create an array of the struct.
Fill the struct array such that the first half the original array are stored in the first member of the elements of struct array and the the second half of the original array are stored in the second member of the elements of the struct array.
Sort the struct array using the first member of the elements.

Just add this code after your last memcpy function:
int j, temp;
for(i = 0; i < n/2; i++)
{
for( j = 0; j < n/2 - 1; j++ )
{
if( firstHalf[j] > firstHalf[j+1] )
{
temp = firstHalf[j];
firstHalf[j] = firstHalf[j+1];
firstHalf[j+1] = temp;
temp = secondHalf[j];
secondHalf[j] = secondHalf[j+1];
secondHalf[j+1] = temp;
}
}
}
I have used basic bubble sort, but you can use any of the advanced sorting algorithms.
The trick, is that you just have to use the firstHalf array when doing the comparison, but when swapping, you swap elements in both the arrays.

Related

printing 2 characters and keeping them through dynamically allocated 2d array

Hello I am trying to print something like this with 2d array.
Note that when user enters the same number, character should be printed above existing char.
EXPECTED RESULTS:
Input 1: 3 //user1 inputs 3
****
****
**x*
Input 2: 1 //user2 inputs 1
****
****
y*x*
Input 3: 1 //user1 inputs 1
****
x***
y*x*
current results:
enter first: 3
3***
***
**x
enter second: 1
1******
******
xx****
enter first: 2
2*********
*********
***xxx***
But keeping printed values on its previous places.
The problem is that they don't get printed in right order. And also it seems that I haven't done the best job with 2d array which is dynamically allocated.
Here is something what I've tried:
#include <stdio.h>
#include <stdlib.h>
int num(int term)
{
int number1;
int number2;
if(term==1)
{
scanf("%d", &number1);
return number1;
}
if (term==2)
{
scanf("%d", &number2);
return number2;
}
return 0;
}
void function(int a, int b, int result[], int size)
{
int i = 0;
int j = 0;
int desired_num = 0;
int count = 0;
int *arr[a];
for (i = 0; i < a; i++)
arr[i] = (int *)malloc(a * sizeof(int));
for (i = 0; i < a; i++)
for (j = 0; j < b; j++)
arr[i][j] = ++count;
for (i = 0; i < a; i++)
{
for (j = 0; j < b; j++)
{
for (int counter = 0; counter < size; counter++)
{
if (arr[i][j] == arr[a - 1][result[counter] - 1])
{
arr[i][j] = desired_num;
}
if (arr[i][j] == desired_num)
{
printf("%s", "x");
}
else
{
printf("*");
}
}
}
printf("\n");
}
}
int main()
{
int counter = 1;
int i = 0;
int given_number;
int array[20];
for (;;)
{
if (counter % 2 != 0)
{
printf("enter first: ");
given_number = num(1);
printf("%d", given_number);
}
else
{
printf("enter second: ");
given_number = num(2);
printf("%d", given_number);
}
array[i] = given_number;
function(3, 3, array, counter);
counter++;
}
return 0;
}
array[i] = given_number;
i is never changed from the value of 0. You are only ever overwriting the first element of array each iteration. The other 19 elements remain in an indeterminate state.
counter and array are passed to function, as size and result respectively:
This means as size is incremented, it is used as a bounds for accessing elements of result; elements that contain indeterminate values.
for (int counter = 0; counter < size; counter++)
{
if (arr[i][j] == arr[a - 1][result[counter] - 1])
This will surely lead to Undefined Behaviour as those indeterminate values are used to index arr, effectively accessing random memory offsets. This fact alone makes it hard to reason about the output you are seeing, as really anything is valid.
While perfectly valid, the variable-length array of dynamic allocations is a somewhat perplexing choice, especially considering you fail to free the memory allocated by malloc when you are done with it.
int *arr[a];
for (i = 0; i < a; i++)
arr[i] = (int *)malloc(a * sizeof(int));
int arr[a][b]; would work, given a and b are not stack-crushingly large values (or non-positive). You are, or would be, bounded by the size of array in main anyway.
The triply nested loop is confused at best. There is only logic for printing the x and * characters, so you obviously will never see a y.
For each element of arr, you iterate through each element of result. If the current element of arr equals the value of the column selected by the current value of result ([result[counter] - 1]) in the last row (arr[a - 1]) you print x, otherwise *.
Again UB from utilizing indeterminate values of result, but you can see you are printing a * b * size characters, plus newlines, each iteration.
This is severely flawed.
Some other things of note:
The two branches of the if .. else statement in the num function do the exact same thing, just with different identifiers.
The two branches of the if .. else statement in main are identical, other than the first printf in each, and the integer value passed to num, which have the same effect.
This means the only thing that needs to branch is the printf argument.
A generic function for getting an integer would work fine
int get_num(void)
{
int n;
if (1 != scanf("%d", &n)) {
fprintf(stderr, "Could not read input.\n");
exit(EXIT_FAILURE);
}
return n;
}
for use inside main
if (counter % 2 == 0)
printf("enter first: ");
else
printf("enter second: ");
given_number = get_num();
A small issue: printf("%d", given_number); is muddling the output slightly.
There is no reason to repeatedly generate the array. Initialize an array in main to serve as the state of the program. Over time, fill it with the users' selections, and simply print the array each iteration.
Make sure to always check the return value of scanf is the expected number of conversions, and ensure the integers provided by the users will not access invalid memory.
Here is a cursory example.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define EMPTY '*'
#define PLAYER_ONE 'X'
#define PLAYER_TWO 'O'
int get_num(void)
{
int n;
if (1 != scanf("%d", &n)) {
fprintf(stderr, "Could not read input.\n");
exit(EXIT_FAILURE);
}
return n;
}
int main(void)
{
const size_t rows = 6;
const size_t cols = 7;
char board[rows][cols + 1];
memset(board, EMPTY, sizeof board);
/* our rows are now strings */
for (size_t i = 0; i < rows; i++) {
board[i][cols] = '\0';
puts(board[i]);
}
unsigned char turn = 1;
while (1) {
printf("Player %s, Enter column #(1-%zu): ",
turn & 1 ? "One" : "Two", rows);
int input = get_num();
if (1 > input || input > cols) {
printf("Invalid column [%d]. Try again...\n", input);
continue;
}
size_t sel = input - 1;
if (board[0][sel] != EMPTY) {
printf("Column [%d] is full! Try again...\n", input);
continue;
}
size_t n = rows;
while (n--) {
if (board[n][sel] == EMPTY) {
board[n][sel] = turn & 1 ? PLAYER_ONE : PLAYER_TWO;
break;
}
}
for (size_t i = 0; i < rows; i++)
puts(board[i]);
turn ^= 1
}
}

in bubble sort how do i implement if the value changed its position then change/assign the previous text name to change its position also

I have a text file where it contains all the data i need then i will read the data and do a bubble sort for Total Vaccines available and using bubble sort i arranged it in descending order but i need help with how to change the Vaccine_Code according the newly arranged Total_Vaccines. Please Help
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct dist
{
char Name_Vaccine[5][15];
char Vaccine_Code[5][10];
char Producing_Country[5][15];
int Dosage_Required[5];
float Population_Covered[5];
float Total_Vaccines[5];
char distcode[100][100];
float distvalue[100];
};
int main()
{
struct dist sort[20];
int i, j, n=5,m;
float a,b;
FILE *f = fopen("vaccine.txt", "r");
FILE *fp = fopen("dist.txt","r");
//For Vaccine.txt
for (int i = 0; i < 5; i++)
{
fscanf(f,"%s",sort->Name_Vaccine[i]);
fscanf(f,"%s",sort->Vaccine_Code[i]);
fscanf(f,"%s",sort->Producing_Country[i]);
fscanf(f,"%d",&sort->Dosage_Required[i]);
fscanf(f,"%f",&sort->Population_Covered[i]);
fscanf(f,"%f",&sort->Total_Vaccines[i]);
}
fclose(f);
//Original Order
printf("The numbers arranged in Original order for Vaccine.txt are given below\n");
for (i = 0; i < n; ++i)
{
printf("%s %.4f\n",sort->Vaccine_Code[i], sort->Total_Vaccines[i]);
}
// sorting begins ... //
for (i = 0; i < n; ++i)
{
for (j = i + 1; j < n; ++j)
{
if (sort->Total_Vaccines[i] < sort->Total_Vaccines[j])
{
a = sort->Total_Vaccines[i];
sort->Total_Vaccines[i] = sort->Total_Vaccines[j];
sort->Total_Vaccines[j] = a;
}
}
}
printf("The numbers arranged in Descending order for Vaccine are given below\n");
for (i = 0; i < n; ++i)
{
printf("%s %9.4f\n",sort->Vaccine_Code[i], sort->Total_Vaccines[i]);
}
return 0;
}
Instead of moving your data it's probably better to just move pointers to your data. Basically you initialize an array of size n with the numbers 0, ..., n - 1. Then you sort the array using the comparison function that compares the values behind the index.
It should look something like the modified code below. But beware, I didn't test it.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define ARRAYSIZE 5
struct dist
{
char Name_Vaccine[5][15];
char Vaccine_Code[5][10];
char Producing_Country[5][15];
int Dosage_Required[5];
float Population_Covered[5];
float Total_Vaccines[5];
char distcode[100][100];
float distvalue[100];
};
int main()
{
struct dist sort[20];
int i, j, n=ARRAYSIZE,m;
int idxArray[ARRAYSIZE];
float a,b;
FILE *f = fopen("vaccine.txt", "r");
FILE *fp = fopen("dist.txt","r");
//For Vaccine.txt
for (int i = 0; i < ARRAYSIZE; i++) {
fscanf(f,"%s",sort->Name_Vaccine[i]);
fscanf(f,"%s",sort->Vaccine_Code[i]);
fscanf(f,"%s",sort->Producing_Country[i]);
fscanf(f,"%d",&sort->Dosage_Required[i]);
fscanf(f,"%f",&sort->Population_Covered[i]);
fscanf(f,"%f",&sort->Total_Vaccines[i]);
idxArray[i] = i; // piggyback initialization of the index array
}
fclose(f);
//Original Order
printf("The numbers arranged in Original order for Vaccine.txt are given below\n");
for (i = 0; i < n; ++i) {
printf("%s %.4f\n",sort->Vaccine_Code[i], sort->Total_Vaccines[i]);
}
// sorting begins ... //
for (i = 0; i < n; ++i) {
for (j = i + 1; j < n; ++j) {
if (sort->Total_Vaccines[idxArray[i]] < sort->Total_Vaccines[idxArray[j]]) {
a = idxArray[i];
idxArray[i] = idxArray[j];
idxArray[j] = a;
}
}
}
printf("The numbers arranged in Descending order for Vaccine are given below\n");
for (i = 0; i < n; ++i) {
printf("%s %9.4f\n",sort->Vaccine_Code[idxArray[i]], sort->Total_Vaccines[idxArray[i]]);
}
return 0;
}
Obviously, with an array size of 5 the exact method doesn't play that much of a role. It would even be acceptable to search for the smallest element, greater than the last written element, for each line printed in the last loop.

Why do I get a segmentation fault by declaring a 2d array in c?

I am new to threads and I have a program that uses threads to find the minimum number out of a 2d array and later on, it finds the distance that the other elements of the array have from the minimum number and stores them in another array.
The user should enter the size of the array and the number of threads he wants to use.
I tried the program below for 1d array and it worked just fine. When I converted it to work for a 2d array it started crashing and throwing a segmentation fault. I, however, cannot find which part of the 2d declaration is wrong.
Any help is really appreciated.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
#include <pthread.h>
struct Parameters
{
// input
int s,p; //n is size of array, p is number of threads
int** array; //array with elements
int start;
int end;
// output
int smallest;
int pos; //position if minimum
int** B; //array that holds the distances
};
void* min(void* args)
{
struct Parameters* p = (struct Parameters*)args;
int **array = p->array;
int **B1 = p->B;
int start = p->start;
int end = p->end;
int smallest = array[start][start];
int pos = p->pos;
int distance;
//find the smallest
for (int i = start; i < end; i++)
{
for(int j = start; j < end; j++)
{
if (array[i][j] < smallest)
{
smallest = array[i][j];
pos = i;
}
}
}
//find the distances
for(int i = 0; i < ((struct Parameters*)args) -> s; i++)
{
for(int j = 0; j < ((struct Parameters*)args) -> s; j++)
{
distance = abs(pos - i);
B1[i][j] = distance;
}
}
params->smallest = smallest;
params->B = B1;
return NULL;
}
int main()
{
int smallest,pos;
int s,p;
struct Parameters *ptr = (struct Parameters *)malloc(sizeof(struct Parameters));
if(ptr == NULL)
{
printf("Not enough. Try again \n");
exit(0);
}
printf("Type s\n");
scanf("%d",&(ptr->s));
printf("Type p\n");
scanf("%d", &(ptr->p));
// declare an array of threads and associated parameter instances
pthread_t threads[(ptr->p)];
struct Parameters thread_parameters[(ptr->p)] ;
int arr[ptr->s][ptr->s];
int B2[ptr->s][ptr->s];
// intialize the array
for(int i=0; i< ptr->s; i++)
{
for(int j=0; j< ptr->s; j++)
{
printf("Type a \n");
scanf("%d",&arr[i][j]);
}
}
// smallest needs to be set to something
smallest = arr[0][0];
// start all the threads
for (int i = 0; i < ptr->p; i++)
{
memcpy(arr, thread_parameters[i].array, sizeof(arr));
thread_parameters[i].s = ptr->s;
memcpy(Bb, thread_parameters[i].B, sizeof(B2));
thread_parameters[i].start = i * (ptr->s / ptr->p);
thread_parameters[i].end = (i+1) * (ptr->s / ptr->p);
pthread_create(&threads[i], NULL, min, &thread_parameters[i]);
}
// wait for all the threads to complete
for (int i = 0; i < ptr->p; i++)
{
pthread_join(threads[i], NULL);
}
// Now aggregate the "smallest" and "largest" results from all thread runs
for (int i = 0; i < ptr->p; i++)
{
if (thread_parameters[i].smallest < smallest)
{
smallest = thread_parameters[i].smallest;
}
}
printf("Smallest is %d\n", smallest);
thread_parameters[ptr->p].B[ptr->s][ptr->s];
for (int i = 0; i < 1; i++)
{
for(int j = 0; j < ptr->s;j++)
{
for(int k = 0; k < ptr->s; k++)
{
printf("Element %d is %d away from min\n",j,thread_parameters[i].B[j][k]);
}
}
}
return 0;
}
Thank you!!
The issue with your code might also come from :
memcpy(arr, thread_parameters[i].array, sizeof(arr));
...
memcpy(Bb, thread_parameters[i].B, sizeof(B2));
as thread_parameters[i].array and thread_parameters[i].B are not allocated, if you are only reading the array it might b fine to only pass them by address
thread_parameters[i].array = arr
but for thread_parameters[i].B you would need to allocate the arrays and perform a deep copy (memcpy would not work)
The below text does not answer the question but does provide some insight on VLA usage
One reason for causing the segmentation with a declaration of a Variable Length Array is that the value is to large to allocate the array on the stack (some compiler choose this option, this choice might have performance reason).
The is not much option to recover cleanly from failure to allocate memory on the stack as there is little way to clean up stack memory during runtime within the same stack context.
You can mitigate the issue by allocating your 2D arrays on the heap instead, some of the strategies are available here(thanks #Lundin) and here.
int** alloc_2d_int_array(size_t rows, size_t cols) {
int **result = malloc(rows * sizeof(int *));
if(result == NULL) {
// could not allocate more memory
return NULL;
}
size_t row_size = cols * sizeof(int);
for(int i=0; i < rows; ++i) {
result[i] = malloc(row_size);
if(result[i] == NULL) {
// could not allocate more memory
// cleanup
return NULL;
}
}
return result;
}
the above implementation have not been tested, but does compile, there are still risk of integer overflow.
Then use the above define function as following:
int **arr = alloc_2d_int_array(ptr->s, ptr->s);
int **B2 = alloc_2d_int_array(ptr->s, ptr->s);
easier implementation (see here(thanks #Lundin))
int **arr = malloc(sizeof(int[ptr->s][ptr->s]);
int **B2 = malloc(sizeof(int[ptr->s][ptr->s]);

how to put numbers from interval to array? (C language)

I am looking for this for a while.
Can anyone tell me how can I create interval array?
Example:
interval = < 4;9 >
int array[9-4+1] = {4,5,6,7,8,9}
I would like to insert number from interval to array and than I can work with values in array.
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int size_Of_Interval;
int a;
int b;
printf("Please specify the starting interval value: ");
scanf("%d", &a);
printf("Please specify the ending interval value: ");
scanf("%d", &b);
size_Of_Interval = (b-a+1);
printf("Interval from %d to %d. Interval has %d numbers\n", a, b, size_Of_Interval);
return 0;
}
If your compiler supports variable length arrays (VLAs) then you can just write
int arr[size_Of_Interval];
for ( int i = 0; i < size_Of_Interval; i++ )
{
arr[i] = a + i;
}
Otherwise you should dynamically allocate an array. For example
int *arr = malloc( size_Of_Interval * sizeof( int ) );
for ( int i = 0; i < size_Of_Interval; i++ )
{
arr[i] = a + i;
}
In this case you will need also to free the array when it will not be needed any more
free( arr );
Before to return from the main:
int *array = malloc(size_of_interval * sizeof(int));
This dynamically allocates the needed amount of memory, returning a pointer to the firts element of an array with size_of_interval length. Afterward you can go through a loop and fill that array:
for(int i = 0; i < size_Of_Interval; i++) {
array[i] = a + i;
}
When you end the job with your array, as commented above, you need to free the resource:
free(array);

Segmentation Fault while allocating memory at run time using malloc [duplicate]

This question already has answers here:
How do I work with dynamic multi-dimensional arrays in C?
(9 answers)
Closed 8 years ago.
This is my code. My purpose is to allocate memory to a 2D array at run time upto whatever size is given in input.
Why is segmentation fault occuring? Is it because array elements have to be stored consecutively and malloc(dynamic allocation) is not letting this happen?
OR I am doing some error in writing this code. Please guide me through.
Thanks in advance.
int main(){
// STEP 1
int size,**arr,i=0,j=0;
printf("Enter the size of matrix : ");
scanf("%d",&size);
// STEP 2
arr = (int**)malloc(size*size*sizeof(int));
printf("\n Enter the %d elements : \n",size*size);
for(i=0;i<size;i++){
for(j=0;j<size;j++){
// STEP 3
scanf("%d",&arr[i][j]);
}
}
/*
for(i=0;i<size;i++){
for(j=0;j<size;j++){
printf("%d\n",matrix[i][j]);
}
}
*/
return 0;
}
This is a classic mistake.
A pointer to pointers is actually not the same as a two-dimensional array.
Granted, you can access elements of both via the var[x][y] syntax, but the memory layout of
int foo[x][y]
is different from
int **bar
If you really want to have this dynamic, you will have to allocate space for your list of pointers, then allocate space for your elements to each pointer in turn.
bar = malloc( x * sizeof(int*) );
for ( int i = 0 ; i < x ; i++ )
bar[i] = malloc( y * sizeof(int) );
If at all possible, you should try and avoid this in favor of an actual two-dimensional array, which as of C99 you can declare on the stack even if its size is determined at runtime:
int main()
{
int n;
scanf("%d", &n);
int array[n][n];
// ...
return 0;
}
You should allocate like this:
arr = malloc(size * sizeof(int*));
for (int i = 0; i <size; i++)
arr[i] = malloc(size * sizeof(int));
And do not forget to free the memeory using free.
Side Note: Do not cast the return value of malloc.
One idea that would work and would also get you rid of the memory fragmentation induced by this double pointers level allocation is make your matrix linear:
arr = (int*) malloc (size*size*sizeof(int));
And then simply access your elements with arr[i*size + j] instead of arr[i][j]:
use it like this : a perfect example of dynamic memory Allocation
void mxmult()
{
int n,m,a,b,c,d, sum=0;
int x,y,z;
printf("Enter first order [n*n]\n");
scanf("%d", &n);
printf("Enter second order [m*m]\n");
scanf("%d", &m);
if (n!=m)
{
printf("Invalid orders");
}
else
{
//mem allocate for matrix 1
int **mat1 = (int**)malloc(n*sizeof(int));
for(x=0;x<n;x++)
{
mat1[x]=(int*)malloc(n*sizeof(int));
}
// input matrix 1
printf("Enter the first matrix entries\n");
for (a = 0; a <n; a++)
{
for (b = 0; b < n; b++)
{
scanf("%d", &mat1[a][b]);
}
}
// memory allocate matrix 2
int **mat2 = (int**)malloc(m*sizeof(int));
for(y=0;y<n;y++)
{
mat2[y]=(int*)malloc(m*sizeof(int));
}
//inpur matrix 2
printf("Enter the second matrix entries\n");
for (c = 0; c <n; c++)
{
for (d= 0; d < n; d++)
{
scanf("%d", &mat2[c][d]);
}
}
//Memory allocate matrix Mult
int **mult=(int**)malloc(m*sizeof(int));
for(z=0;z<m;z++)
mult[z]=(int*)malloc(m*sizeof(int));
for (a = 0; a < n; a++)
{
for (d = 0; d < m; d++)
{
for (c = 0; c < n; c++)
{
sum=sum + (mat1[a][c] *mat2[c][d]);
}
mult[a][d] = sum;
sum= 0;
}
}
printf("Product\n");
for ( a = 0 ; a < n ; a++ )
{
for ( d = 0 ; d < m ; d++)
printf("%d\t", mult[a][d]);
printf("\n");
}
}
}

Resources