Converting a 1D Array to a Matrix - c

I have a single dimensional array with the following values:
10010011
I would like to convert this single dimensional array to a 2X4 Matrix with the following order:
1001
0011
The code that I attempted is below:
#include <stdio.h>
#include <stdlib.h>
#define rows_Matrix 2
#define cols_Matrix 4
void print2DArray(unsigned **arr, int m, int q);
int main()
{
int k = 0;
unsigned Array[8] = { 1, 0, 0, 1, 0, 0, 1, 1};
//Allocation of Memory.
unsigned **Matrix = (unsigned **)malloc(sizeof(unsigned *)*rows_Matrix); //Rows
for (int i = 0; i < rows_Matrix; i++) //Rows
{
Matrix[i] = (unsigned *)malloc(sizeof(unsigned ) * cols_Matrix); //Columns
}
do
{
for (int i = 0; i < rows_Matrix; i++)
{
for (int j = 0; j < cols_Matrix; j++)
{
Matrix[i][j] = Array[k];
}
}
k++;
} while (k < 8);
print2DArray(Matrix, 2, 4);
return 0;
}
void print2DArray(unsigned **arr, int m, int q)
{
for (int i = 0; i < m; i++) //Rows
{
for (int j = 0; j < q; j++)//Columns
{
printf("%d\t", arr[i][j]);
}
printf("\n");
}
printf("\n");
}
But the answer that I am getting is:
1 1 1 1
1 1 1 1
I would like to know why the values values are not being assigned correctly. It seems the way I am doing it I am just copying the first element of the single dimensional array.

You have incremented in the wrong place. So Array[k] was indicating the same element.
#include <stdio.h>
#include <stdlib.h>
#define rows_Matrix 2
#define cols_Matrix 4
void print2DArray(unsigned **arr, int m, int q);
int main()
{
int k = 0;
unsigned Array[8] = { 1, 0, 0, 1, 0, 0, 1, 1};
//Allocation of Memory.
unsigned **Matrix = (unsigned **)malloc(sizeof(unsigned *)*rows_Matrix); //Rows
for (int i = 0; i < rows_Matrix; i++) //Rows
{
Matrix[i] = (unsigned *)malloc(sizeof(unsigned ) * cols_Matrix); //Columns
}
do
{
for (int i = 0; i < rows_Matrix; i++)
{
for (int j = 0; j < cols_Matrix; j++)
{
Matrix[i][j] = Array[k];
k++; //updated
}
}
} while (k < 8);
print2DArray(Matrix, 2, 4);
return 0;
}
void print2DArray(unsigned **arr, int m, int q)
{
for (int i = 0; i < m; i++) //Rows
{
for (int j = 0; j < q; j++)//Columns
{
printf("%d\t", arr[i][j]);
}
printf("\n");
}
printf("\n");
}

Related

How to use a pointer (to a Matrix) as an argument in a Function in C?

I'm trying to write a code in C that sum two 4x4 matrix.
But I want my function to have a pointer as my arguments. The only error I'm getting is the time I'm trying to sum up in the function. Could someone help me?
#include <stdio.h>
#include <locale.h>
int i = 0, j = 0;
void calc_soma(int* mat_A, int* mat_B, int* mat_C)
{
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
mat_C[i][j] = mat_A[i][j] + mat_B[i][j];
printf("%d", mat_C[i][j]);
}
}
}
int main()
{
setlocale(LC_ALL, "Portuguese");
int i=0, j=0;
int mA[4][4], mB[4][4], mC[4][4];
int *mat_A, *mat_B, *mat_C;
for(i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
printf("Type in the value for Matrix A [%d][%d]: ", i, j);
scanf_s("%d", &mA[i][j]);
}
}
i, j = 0;
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
printf("Type in the value for Matrix B [%d][%d]: ", i, j);
scanf_s("%d", &mB[i][j]);
}
}
*mat_A = &mA;
*mat_B = &mB;
return 0;
}
The types of pointers for the arguments are wrong. You want to pass (the pointer to the first elements of) arrays like int mA[4][4];, so they should be pointers to int[4].
void calc_soma(int (*mat_A)[4], int (*mat_B)[4], int (*mat_C)[4])
{
/* same as original */
}
They can simply be written like this:
void calc_soma(int mat_A[][4], int mat_B[][4], int mat_C[][4])
{
/* same as original */
}
Then the function can be called like:
calc_soma(mA, mB, mC);
The purpose of mat_A and mat_B are unclear, but if you want to get pointers to the matrice like &mA, it should be int(*)[4][4]. Note that dereferencing (like *mat_A) uninitialized pointers will invoke undefined behavior.
int main()
{
setlocale(LC_ALL, "Portuguese");
int i=0, j=0;
int mA[4][4], mB[4][4], mC[4][4];
int (*mat_A)[4][4], (*mat_B)[4][4], (*mat_C)[4][4];
/* omit */
mat_A = &mA;
mat_B = &mB;
return 0;
}
To use functions like
void calc_soma(int* mat_A, int* mat_B, int* mat_C)
you should express the matrice by 1D array to match with the format. It will be like this:
#include <stdio.h>
#include <locale.h>
#define ROWS 4
#define COLS 4
int i = 0, j = 0;
void calc_soma(int* mat_A, int* mat_B, int* mat_C)
{
for (i = 0; i < ROWS; i++)
{
for (j = 0; j < COLS; j++)
{
mat_C[i * COLS + j] = mat_A[i * COLS + j] + mat_B[i * COLS + j];
printf("%d", mat_C[i * COLS + j]);
}
}
}
int main()
{
setlocale(LC_ALL, "Portuguese");
int i=0, j=0;
int mA[ROWS * COLS], mB[ROWS * COLS], mC[ROWS * COLS];
for(i = 0; i < ROWS; i++)
{
for (j = 0; j < COLS; j++)
{
printf("Type in the value for Matrix A [%d][%d]: ", i, j);
scanf_s("%d", &mA[i * COLS + j]);
}
}
i, j = 0;
for (i = 0; i < ROWS; i++)
{
for (j = 0; j < COLS; j++)
{
printf("Type in the value for Matrix B [%d][%d]: ", i, j);
scanf_s("%d", &mB[i * COLS + j]);
}
}
calc_soma(mA, mB, mC);
return 0;
}

Rotating the array using C

Why this code is giving segmentation fault error?
This is code using for loop for left shift the given array at stdin by no of rotations.
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int *rotatebyone(int *array_input, int len_of_arr);
void rotate(int *array_input, int len_of_arr, int no_of_rota);
int main()
{
int array1[] = { };
int array2[] = { };
int array3[] = { };
int i = 0, j = 0, size_of_arr = 0, no_of_rotations = 0;
for (i = 0; i < 2; i++)
{
scanf("%d", &array1[i]);
//printf("%d", array1[i]);
}
size_of_arr = array1[0];
no_of_rotations = array1[1];
for (i = 0; i < size_of_arr; i++)
{
scanf("%d", &array2[i]);
//printf("%d ", array2[i]);
}
rotate(array2, size_of_arr, no_of_rotations);
return 0;
}
void rotate(int *array_input, int size_of_array, int no_of_rota)
{
int h = 0;
for (h = 0; h < no_of_rota; h++)
{
rotatebyone(array_input, size_of_array);
}
for (h = 0; h < size_of_array; h++)
printf("%d ", array_input[h]);
}
int *rotatebyone(int *array_input1, int len_of_arr)
{
//int array3 = {};
int j = 0, k = 0;
int temp = 0;
temp = array_input1[0];
for (k = 0; k < len_of_arr - 1; k++)
{
array_input1[k] = array_input1[k + 1];
}
array_input1[len_of_arr - 1] = temp;
return array_input1;
}
For array2[], you have not mentioned its size. It can be evn 1000 or 10000. Better use int * array2 and allot memory through malloc.
Reg array1, it can be initialesed as int array1[2] since we know two elements are there for array1.

How to use second rank pointer rightly?

I have a 2D array called matrix, now I would like to add one to every element.
#include <stdio.h>
#include <stdlib.h>
int **add_one(int **matrix, int m, int n) {
int i, j;
int **new_mat;
new_mat = (int **) malloc(m * n *sizeof(int));
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
new_mat[i][j] = matrix[i][j] + 1;
}
}
//return the 2nd rank pointer
return new_mat;
}
int main() {
int matrix[3][2] = {1, 2, 3, 4, 5, 6};
int **new_mat;
int i, j;
new_mat = add_one(matrix, 3, 2);
for (i = 0; i < 3; i++) {
for (j = 0; j < 2; j++) {
printf("%d ", new_mat[i][j]);
}
printf("\n");
}
free(new_mat);
}
However, the compiler told me that
[Error] cannot convert 'int (*)[2]' to 'int**' for argument '1' to 'int** add_one(int**, int, int)'
It works a bit differently from what you thought
#include <stdio.h>
#include <stdlib.h>
// you can only pass what you have
int **add_one(int matrix[3][2], int m, int n)
{
int i, j;
int **new_mat;
// allocate m pointers (the rows)
new_mat = malloc(m * sizeof(*new_mat));
for (i = 0; i < m; i++) {
// allocate space for n ints
new_mat[i] = malloc(n * sizeof(int));
for (j = 0; j < n; j++) {
new_mat[i][j] = matrix[i][j] + 1;
}
}
//return the 2nd rank pointer
return new_mat;
}
int main()
{
// you forgot to encapsulate the rows, too
int matrix[3][2] = { {1, 2}, {3, 4}, {5, 6} };
int **new_mat;
int i, j;
new_mat = add_one(matrix, 3, 2);
for (i = 0; i < 3; i++) {
for (j = 0; j < 2; j++) {
printf(" %d ", new_mat[i][j]);
}
printf("\n");
}
free(new_mat);
}
If you want to pass the two-star matrix as a two-star matrix you need to build it like the new_mat in the function add_one.

Taking the transpose of a matrix in C with 1D arrays

I have a matrix that is represented by a one dimensional array,
example:
the matrix
0 1 2 3
4 5 6 7
8 9 10 11
the array
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
now give the dimensions of this matrix and the array I want to find the transpose, i.e.
0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11
I'm working in C and here is my code
#include <stdlib.h>
#include <stdio.h>
void transpose(int *array, int m, int n){
int new_array[12];
for (int i=0; i<m*n; i++) {
new_array[i] = ??;
}
for (int i=0; i<m*n; i++) {
array[i] = new_array[i];
}
}
void print_array(int array[], int size){
for (int i=0; i<size; i++) {
printf("%d\n",array[i]);
}
}
int main(){
int array[12];
for (int i=0; i<12; i++) {
array[i]=i;
}
print_array(array,12);
transpose(array,3,4);
print_array(array,12);
return 0;
}
I've tried a dozen times and failed. Is there a simple way to do this that I have missed?
Use couple of for loops to make the code easier to follow.
void transpose(int *array, int m, int n){
int new_array[12];
for (int i = 0; i < m; ++i )
{
for (int j = 0; j < n; ++j )
{
// Index in the original matrix.
int index1 = i*n+j;
// Index in the transpose matrix.
int index2 = j*m+i;
new_array[index2] = array[index1];
}
}
for (int i=0; i<m*n; i++) {
array[i] = new_array[i];
}
}
void transpose(int *array, int m, int n){
int new_array[12];
int k = 0;
for(int i = 0; i < n; i++){
for (int j = 0; j < m; j++){
new_array[k++] = array[j*n + i];
}
}
for (int i=0; i<m*n; i++) {
array[i] = new_array[i];
}
}
Write the transpose in terms of a double loop over range [0..n) and [0..m) and calculate the indexes corresponding to the old position and the new position:
#include <stdio.h>
static void transpose(int *array, int m, int n)
{
int new_array[m * n];
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
int old_idx = i * n + j;
int new_idx = j * m + i;
new_array[new_idx] = array[old_idx];
}
}
for (int i = 0; i < m * n; i++)
{
array[i] = new_array[i];
}
}
static void print_array(int array[], int size)
{
for (int i = 0; i < size; i++)
{
printf(" %d", array[i]);
}
putchar('\n');
}
int main(void)
{
int array[12];
for (int i = 0; i < 12; i++)
{
array[i] = i;
}
print_array(array, 12);
transpose(array, 3, 4);
print_array(array, 12);
return 0;
}
The functions have to be pre-declared or made static to compile with my default compilation options. The transpose() function shown will work with any shape (size) of matrix (whereas the original won't work if the product of the dimensions is more than 12). I flattened the output from the array printer, too (though I'd probably make it print matrix shaped output if it were for 'production' use). I do assume that you have C99, or C11 with VLA support.
$ ./trans
0 1 2 3 4 5 6 7 8 9 10 11
0 4 8 1 5 9 2 6 10 3 7 11
$
I have changed:
for (int i = 0 ; i < m*n ; i++) {
new_array[i] = ??;
}
to:
int ctr = 0;
for (int i = 0 ; i <= m*n ; i++) {
if (ctr > m*n)
ctr -= m*n - 1;
new_array[i] = array[ctr];
ctr += n;
}
The logic is quite simple. Each row is n integers long and so the number below a num in the 2-D matrix form would be n+num
You can rewrite your transpose function as like this:
static void transpose(int *array, int m, int n)
{
int *temp=malloc(m*n*sizeof(int)); //need to create a temporary array.
memcpy(temp,array,m*n*sizeof(int));
int i, j;
for (i = 0; i < m; ++i)
{
for (j = 0; j < n; ++j)
{
array[j*m+i]=temp[i*n+j];
}
}
free(temp);
}
You almost had it, I think this would do it...
void transpose(int *array, int m, int n){
int new_array[12];
int count;
count = 0;
for (int i=0; i < n; i++) {
for (int j=0; j < m; j += n) {
new_array[count++] = i + j;
}
}
for (int i=0; i < m * n; i++) {
array[i] = new_array[i];
}
}
This algorithm works for any number of rows an columns:
for (std::size_t i = 0; i < col; i++) {
for (std::size_t j = 0; j < row; j++) {
transpose[c++] = array[j * col + i];
}
}

Sorting integer array to avoid repeating consecutive values in C

I'm using Linux to implement this sorting. If I have a array arr[] ={1, 1, 1, 2, 2, 3, 3}, how to sort it by this:
arr[0] = 1
arr[1] = 2
arr[2] = 3
arr[3] = 1
arr[4] = 2
arr[5] = 3
arr[6] = 1
I Tried to do something like this:
for (int i = 0; i < size; i++)
{
if (arr[i] < arr[i+1])
{
}
}
Please give me some suggestions, thank you so much!
a hint
first you have to sort the array, then starting from 1 to (end-1) if active item equals to the last item move it to the end.
#include <stdio.h>
#include <stdlib.h>
/*__________________________________________________
*/
static int __cdecl sortCallback(int *i1,int *i2){
return (*i1<*i2)?-1:(*i1>*i2)?1:0;
}
/*__________________________________________________
*/
void printArr(char* Title,int *arr,int n){
int i;
if(Title)
printf("%s:\n\t",Title);
for (i=0;i<n;i++)
printf("%d ",arr[i]);
printf("\n");
return;
}
/*__________________________________________________
*/
void arrange(int *arr,int n){
int i=1,j;
int a;
while(i<(n-1)){
if(arr[i]==arr[i-1]){
a=arr[i];
for(j=i;j<(n+1);j++){
arr[j]=arr[j+1];
}
arr[n-1]=a;
}else
i++;
}
}
/*__________________________________________________
*/
int main(void){
int arr[7];
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
arr[3] = 1;
arr[4] = 2;
arr[5] = 3;
arr[6] = 1;
printArr("Initial",arr,7);
qsort(arr,7,sizeof(int),sortCallback);
printArr("Sorted",arr,7);
arrange(arr,7);
printArr("Rearranged",arr,7);
return 0;
}
#include <stdio.h>
void cnv(int n, int arr[n]){//arr is sorted
struct {
int value;
int occurs;
} tmp[n];
//make distinct array
int k = 0;
tmp[k].value = arr[0];
tmp[k].occurs = 1;
for(int i = 1; i < n; ++i){
if(arr[i] != arr[i-1]){
tmp[++k].value = arr[i];
tmp[k].occurs = 1;
} else {
++tmp[k].occurs;
}
}
//Written back
for(int i = 0, j = 0; i < n; ++i){
while(tmp[j].occurs == 0){
j = (j == k) ? 0 : j + 1;
}
arr[i] = tmp[j].value;
--tmp[j].occurs;
j = (j == k) ? 0 : j + 1;
}
}
int main(void){
int arr[] ={1, 1, 1, 2, 2, 3, 3};
int n = sizeof(arr)/sizeof(*arr);
cnv(n, arr);
for(int i = 0; i < n; ++i) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}

Resources