Reconstructing an array in c - c

Given a sparse vector (more 0s than other elements), make a function to split the vector up into two vectors (one containing the elements, and the other containing the position of the elements. Make another function to reconstruct the source vector from the position and value arrays (including the 0s in the original source).
So this doesn't reconstruct it properly - and I don't understand why. I tested the arrays val and pos in the main function, but they don't have the right numbers in them.
Here's what I have so far:
for the efficient representation (splitting the source vector into two parts):
void efficient( const int source[], int val[], int pos[], int size)
{
int j = 0;
for (j = 0; j < size; j++)
{
if (source[j] != 0)
{
val[j] = source[j];
pos[j] = j;
}
}
}
for the reconstruct function (m is size of source vector being reconstructed, n is size of position and value vectors):
void reconstruct( int source[], int m, const int val[], const int pos[], int n) {
int i = 0;
int j = 0;
int k = 0;
for (i = 0; i < m; i++)
source[i] = 0; // sets all elements in source array equal to 0
for (j = 0; j < n; j++){
source[pos[j]] = val[j];
}
for (k = 0; k < m; k++)
printf("%d ", source[k]);
}
and here's my main test function:
int main()
{
int i;
int size;
const int source[] = {0,0,23,0,-7,0,0,48};
int val[3] ;
int pos [3] ;
efficient(source,val,pos,8); // calls function efficient
reconstruct(source, 8, val, pos, 3); // calls function reconstruct with parameters source, source size = 8, value array, position array and size of value and position array
}
So this doesn't reconstruct it properly - and I don't understand why. I tested the arrays val and pos in the main function, but they don't have the right numbers in them.

void efficient( const int source[], int val[], int pos[], int size)
{
int j = 0;
for (j = 0; j < size; j++)
{
if (source[j] != 0)
{
val[j] = source[j]; <-- HERE
pos[j] = j;
}
}
}
You don't mean val[j]. You need a separate variable to count the number of entries in val and pos. Perhaps:
void efficient( const int source[], int val[], int pos[], int size)
{
int j, p;
for (j = 0, p = 0; j < size; j++)
{
if (source[j] != 0)
{
val[p] = source[j];
pos[p] = j;
++p;
}
}
}

Related

Unable to find the optimal cost of pairing elements of two sets

Given two sets of natural number A and B of size n such that each member of A has to be paired to at at most one member of B. There is also cost associated with each pairing i.e if the absolute difference b\l sum of all n-length possible pair permutations of elements of A with B.
The following (crude and far from being optimized and safe -- I used a global variable: horror!) code does the job:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define SWAP(x, y, T) do { T SWAP = x; x = y; y = SWAP; } while (0)
int factorial(int N) {
int product = 1;
for (int j = 1; j <= N; j++)
product *= j;
return product;
}
// Prints the array
void printArr(int a[], int n)
{
for (int i = 0; i < n; i++) {
printf("%d ", a[i]);
}
printf("\n");
}
// Stores the array
void storeArr(int a[], int n, int counter, int** out)
{
for (int i = 0; i < n; i++) {
out[counter][i] = a[i];
}
}
int get_cost(int a, int b) {
int diff = abs(a - b);
if (diff >= 5 && diff < 10) {
return 0;
}
else if (diff < 5) {
return 1;
}
else {
return 2;
}
}
int cost_perm(int* a, int* b, int n) {
int cost = 0;
for (int i = 0; i < n; ++i) {
cost += get_cost( a[i], b[i] );
}
return cost;
}
// Globals are bad but...
int counter;
// Generating permutation using Heap Algorithm
void heapPermutation(int a[], int size, int n, int** out)
{
// if size becomes 1 then stores the obtained
// permutation
if (size == 1) {
storeArr(a, n, counter++, out);
return;
}
for (int i = 0; i < size; i++) {
heapPermutation(a, size - 1, n, out);
// if size is odd, swap 0th i.e (first) and
// (size-1)th i.e (last) element
if (size % 2 == 1)
SWAP(a[0], a[size - 1], int);
// If size is even, swap ith and
// (size-1)th i.e (last) element
else
SWAP(a[i], a[size - 1], int);
}
}
// Driver code
int main()
{
int a[] = { 169, 165, 161, 131, 145 };
int b[] = { 214, 174, 218, 188, 168 };
int n = sizeof a / sizeof a[0];
int numperm = factorial(n);
int** perm_of_a = calloc(numperm, sizeof(int*));
int** perm_of_b = calloc(numperm, sizeof(int*));
for (int i = 0; i < numperm; ++i) {
perm_of_a[i] = calloc(n, sizeof(int));
perm_of_b[i] = calloc(n, sizeof(int));
}
counter = 0;
heapPermutation(a, n, n, perm_of_a);
counter = 0;
heapPermutation(b, n, n, perm_of_b);
int min_cost = 1000;
int cost;
int mina = 0;
int minb = 0;
for (int i = 0; i < numperm; ++i) {
for (int j = 0; j < numperm; ++j) {
cost = cost_perm(perm_of_a[i], perm_of_b[j], n);
if (cost < min_cost) {
min_cost = cost;
mina = i;
minb = j;
}
}
}
printArr( perm_of_a[mina], n );
printArr( perm_of_b[minb], n );
printf( "%d\n", min_cost );
return 0;
}
You are trying to find one individual pair at each iteration, but you want to minimize the cost over all permutations.
You need to figure out how to generate all permutations of a vector and use code like this:
for permuted_A in all_permutations_of_A
for permuted_B in all_permutations_of_B
cost = cost(permuted_A, permuted_B)
if cost < min_cost
min_cost = cost
min_permuted_A = permuted_A
min_permuted_B = permuted_B
Once you figure out how to enumerate the permutations, the rest will be trivial.

C pointer to 2d array

So i'm creating a loop which can create a 3x3 board by setting the elements of a [3][3] array to enum EMPTY. While debugging, I can see that the program sets the first three elements of the array correctly before getting a memory access violation error, so I know this is a problem with the address of the second row of the array (when the 'i' variable turns from 0 to 1). How do I solve this? pointers are still a bit confusing to me tbh.
int main(void)
{
int board[3][3] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int* p = &board;
create_board(p);
print_board(p);
return 0;
}
void create_board(int *board)
{
for (int i = 0; i < 3; ++i)
{
for (int k = 0; k < 3; ++k)
{
(&board)[i][k] = EMPTY;
}
}
return;
}
Your code has many issues. Arrays in C do not hold any information about their sizes.
The easiest way is to use a pointer to the array:
void create_board(size_t rows, size_t cols, int (*board)[rows])
{
for (size_t i = 0; i < rows; ++i)
{
for (size_t k = 0; k < cols; ++k)
{
board[i][k] = EMPTY;
}
}
}
and main
int main(void)
{
int board[3][3];
create_board(3,3, board);
print_board(3,3,board);
return 0;
}
Similar way you can write print_board function:
void print_board(size_t rows, size_t cols, int (*board)[rows])
{
for (size_t i = 0; i < rows; ++i)
{
for (size_t k = 0; k < cols; ++k)
{
printf("[%zu][%zu] = %d\t", i, k, board[i][k]);
}
printf("\n");
}
}
Your code is invalid. The compiler should issue a message that there are used incompatible pointer types in this declaration
int* p = &board;
The initializing expression has the type int ( * )[3][3] while the initialized object has the type int *.
The function can be declared either like
void create_board( int ( *board )[3], size_t n )
{
for (size_t i = 0; i < n; ++i)
{
for (size_t k = 0; k < 3; ++k)
{
board[i][k] = EMPTY;
}
}
}
and called like
int ( *p )[3] = board;
create_board( p, 3 );
Or if your compiler supports variable length arrays then like
void create_board( size_t m, size_t n, int ( *board )[n] )
{
for (size_t i = 0; i < m; ++i)
{
for (size_t k = 0; k < n; ++k)
{
board[i][k] = EMPTY;
}
}
}
and called like
int ( *p )[3] = board;
create_board( 3, 3, p );

I'm having some troubles understanding how pointers work in c

So I try to do the Heap Sort in C for a row of an 2d array
So basically I find the smallest sum of all the rows from the array and I try to sort the elements of that row, for that I'm trying to store the index of the smallest row with a pointer but when I use pointer the programm it's not returning the index but the adress
//funcion to find the smallest row sum
void min_rand(int(*a)[50], int n, int m, int *mi)
{
int min_row = 0;
int i, j;
for (j = 0; j < m; j++)
min_row += a[0][j];
for (i = 0; i < n; i++) {
int sum_row = 0;
for (j = 0; j < m; j++)
sum_row += a[i][j];
if (sum_row < min_row) {
min_row = sum_row;
*mi = i;
}
}
}
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void heapify_c(int(*a)[50], int n, int i, int mi)
{
int largest = i;
int l = 2 *i + 1;
int r = 2 *i + 2;
if (l < n && a[mi][l] > a[mi][largest])
largest = l;
if (r < n && a[mi][r] > a[mi][largest])
largest = r;
if (largest != i) {
swap(&a[mi][i], &a[mi][largest]);
heapify_c(a, n, largest, mi);
}
}
void heapSort_c(int(*a)[50], int n, int mi)
{
for (int i = n / 2 - 1; i >= 0; i--)
heapify_c(a, n, i, mi);
for (int i = n - 1; i > 0; i--) {
swap(&a[mi][0], &a[mi][i]);
heapify_c(a, i, 0, mi);
}
}
int main()
{
int a[50][50];
int n, m, mi;
min_rand(a, n, m, &mi);
heapSort_c(a, n, mi);
return 0;
}
I don't print the sorted elements in the e.g. above but I just want to know if I'm doing something so terrebly wrong cause I did this before with counting sort and it worked without any problems

How to write a comparator function for qsort for a 2D array?

I have an n*2 sized array. I want to sort them using qsort based on their value of the 2nd column.
#include<stdio.h>
int cmp(const int **a, const int **b) {
//return 0;
//return *a[1] - *b[1]
// return *a - *b;
}
int main()
{
int t; // test cases
scanf("%d", &t);
for(int i=0; i<t; i++) {
int n;
scanf("%d", &n); // size of array
int **arr = (int **)malloc(n * sizeof(int *));
for(int j =0; j< n; j++) {
arr[j] = (int *) malloc(2*sizeof(int));
}
for(int j =0; j< 2; j++) {
for(int k =0; k< n; k++) {
scanf("%d", &arr[k][j]);
}
}
for(int k =0; k< n; k++) {
for(int j =0; j<= 1; j++) {
printf("%d\t", arr[k][j]);
}
printf("\n");
}
// qsort(arr, n, sizeof(arr[0]), cmp);
}
return 0;
}
So for input,
1 2
3 6
0 8
5 4
8 9
5 7
Output is,
1 2
5 4
3 6
5 7
0 8
8 9
I tried but couldn't sort them according to their 2nd column. I am confused with passing array element to the comparator. Also with what to pass as the size of the element? But I guess that first 2 among below are correct.
qsort(arr, n, sizeof(arr[0]), cmp);
//qsort(arr, n, sizeof((int *)), cmp);
//qsort(arr, n, 2 * sizeof((int)), cmp);
I tried various combinations for the comparator.
Please hint out the way or perhaps an explanation.
The prototype for the comparison function is specified in the prototype for the qsort function:
void qsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
Your comparison function must be compatible, so you can define it this way:
int cmp(const void *a, const void *b) {
/* a and b are pointers to the array of pointers. */
int *aa = *(int * const *)a;
int *bb = *(int * const *)b;
return (aa[1] > bb[1]) - (aa[1] < bb[1]);
}
Or without casts:
int cmp(const void *a, const void *b) {
/* a and b are pointers to the array of pointers. */
int * const *aa = a;
int * const *bb = b;
int ia = (*aa)[1];
int ib = (*bb)[1];
return (ia > ib) - (ia < ib);
}
Note that you cannot use the simplistic comparison aa[1] - bb[1] as it can overflow for large values and at best produce incorrect output.
Furthermore, you input loop is incorrect: you should nest the loops in the opposite order:
for (int k = 0; k < n; k++) {
for (int j = 0; j < 2; j++) {
scanf("%d", &arr[k][j]);
}
}
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
int cmp(const void *a, const void *b) {
/* a and b are pointers to the array of pointers. */
int * const *aa = a;
int * const *bb = b;
int ia = (*aa)[1];
int ib = (*bb)[1];
return (ia > ib) - (ia < ib);
}
int main() {
int t; // test cases
scanf("%d", &t);
for (int i = 0; i < t; i++) {
int n;
scanf("%d", &n); // size of array
int **arr = malloc(sizeof(*arr) * n);
for (int j = 0; j < n; j++) {
arr[j] = malloc(sizeof(*arr[j]) * 2);
}
for (int k = 0; k < n; k++) {
for (int j = 0; j < 2; j++) {
scanf("%d", &arr[k][j]);
}
}
qsort(arr, n, sizeof(arr[0]), cmp);
for (int k = 0; k < n; k++) {
for(int j = 0; j < 2; j++) {
printf("%d\t", arr[k][j]);
}
printf("\n");
}
for (int j = 0; j < n; j++) {
free(arr[j]);
}
free(arr);
}
return 0;
}
You can also simplify the code using an actual 2D array:
#include <stdio.h>
#include <stdlib.h>
int cmp(const void *a, const void *b) {
const int *aa = a;
const int *bb = b;
return (aa[1] > bb[1]) - (aa[1] < bb[1]);
}
int main() {
int t; // test cases
scanf("%d", &t);
for (int i = 0; i < t; i++) {
int n;
scanf("%d", &n); // size of array
int (*arr)[2] = malloc(sizeof(*arr) * n);
for (int k = 0; k < n; k++) {
scanf("%d%d", &arr[k][0], &arr[k][1]);
}
qsort(arr, n, sizeof(arr[0]), cmp);
for (int k = 0; k < n; k++) {
printf("%d\t%d\n", arr[k][0], arr[k][1]);
}
free(arr);
}
return 0;
}
First of all you don't have a 2D array. You have a 1D array of pointers that each points to a 1D array of int.
So what you can do is to sort the 1D array of pointers. For that you can write a compare function that looks at the value of the pointed-to element.
It could look something like:
int cmp(const void * a, const void * b)
{
int* const * x = a;
int* const * y = b;
if ((*x)[1] < (*y)[1]) return -1;
if ((*x)[1] > (*y)[1]) return 1;
return 0;
}
As said above: It's the array of pointers that is sorted. You can visualize it like:

How to write all combination with given array

I have some array with numbers. When I want to write all combination with 3 digits I wrote this. But now I need edit this code to return all combination with 1 to numbers.size digits. How should I edit it ?
int items[] = {1, 2, 3, 4, 5};
int itemSize = 5;
for (int i = 0; i < itemSize - 2; i++) {
for (int j = i + 1; j < itemSize - 1; j++) {
for (int k = j + 1; k < itemSize; k++)
printf("%d%d%d\n", items[i], items[j], items[k]);
}
}
it is not perfect solution, but it is well enough to work. you can get all sub array from an array, from 1 element to length array
void permute(char* previous, char *a, int i, int n,int nmax)
{
int j;
if (i == n)
{
char c = a[nmax];
a[nmax] = 0;
if (strstr(previous,a) == 0)
{
printf("%s\n", a);
strncpy(previous,a,n);
}
a[nmax] = c;
}
else
{
for (j = i; j < n; j++)
{
char c = a[i];
a[i] = a[j];
a[j] = c;
permute(previous,a, i+1, n,nmax);
c = a[i];
a[i] = a[j];
a[j] = c;
}
}
}
void subarrays(char *a, int len)
{
int i=1;
char *previous = strdup(a);
*previous = 0;
for(i=1;i<len+1;i++)
{
permute(previous,a,0,len,i);
}
}
int main(void) {
char *arr = strdup("abcde");
subarrays(arr,strlen(arr));
return EXIT_SUCCESS;
}
Since you're already doing a web search for this, here is a generic solution.
#include <stdio.h>
int next_combination(size_t *I, size_t k, size_t n)
{
size_t i, j;
i = k-1; /* find next element to increment */
while(I[i] == (n-k+i)){
--i;
if(i == (size_t)-1){ /* if done */
for(i = 0; i < k; i++) /* return with initial combination */
I[i] = i;
return(0);
}
}
I[i] += 1; /* increment element */
for(j = i+1; j < k; j++) /* create increasing string */
I[j] = I[i]+j-i;
return(1); /* return with new combination */
}
int main(int argc, char **argv)
{
int A[5] = {1, 2, 3, 4, 5};
size_t I[5];
size_t i, k, n;
n = sizeof(A)/sizeof(A[0]); /* n things */
for(k = 1; k <= n; k++){ /* n things k at a time */
for(i = 0; i < k; i++) /* create initial combination */
I[i] = i;
do{ /* display combinations */
for(i = 0; i < k; i++)
printf("%2d", A[I[i]]);
printf("\n");
}
while(next_combination(I, k, n));
}
return(0);
}

Resources