transpose non-square matrix in C - c

everyone I am trying to work on the transpose matrix
here is my code so far.
void Transpose(int mt[][10], int m, int n)
{
int c,d,temp;
for (c = 0; c < m; c++)
{
for (d = c+1; d < n; d++)
{
temp = mt[c][d];
mt[c][d]=mt[d][c];
mt[d][c] = temp;
}
}
}
void print(int pose[][10], int m, int o)
{
int i,j;
for(i = 0; i < m; i++)
{
for(j = 0; j < o; j++)
{
printf("%d\n",pose[j][i]);
}
}
}
int main()
{
/*The body of your source code will go here */
int a[4][5] = {{1,2,3,4,5},{6,7,8,9,10},{10,9,8,7,6},{5,4,3,2,1}};
printf("ARRAY: %d",a[][5]);
Transpose();
return (0);
}
Here is my function for print and transpose a matrix, but now I am trying to pass the array into the function from my main. I just wondering how I declare the array that in the main can pass to the function. Thanks

Your declaration of Transpose does not match your use of it. Since it is declared as:
void Transpose(int mt[][10], int m, int n) {...}
It should be invoked by
Transpose(a, 4, 5);
Also, what is the 10 for? And, the statement
printf("ARRAY: %d", a[][5]);
is unlikely to work.
You should choose better names for your variables. Instead of m and n, use nRows and nColumns. Use row and column instead of i and j.

You can use the following code to do it.
#include<stdio.h>
// Print Matrix
void printArr(int *A, int row,int col)
{
int i,j;
for(i=0;i<row;i++)
{
printf("\n");
for(j=0;j<col;j++)
printf("%d\t",*(A+(col*i)+j));
}
}
//Find the Transpose(TA) of Matrix(A)
void Transpose(int *A,int *TA,int row,int col)
{
int i,j;
for(i=0;i<row;i++)
for(j=0;j<col;j++)
*(TA+(j*row)+i)=*(A+(col*i)+j);
}
// Start of Main
int main()
{
int A[4][5]={{1,2,3,4,5},{6,7,8,9,10},{10,9,8,7,6},{5,4,3,2,1}};
int *TA=malloc(sizeof(int)*4*5); // Allocate Memory for TA
int i,j;
printf("Matrix A:");
printArr(A,4,5); //Print Array A
Transpose(A,TA,4,5); //Call Transpose
printf("\nTranspose Matrix A:");
printArr(TA,5,4); // Print Array TA
return 0;
}
Output:
Matrix A:
1 2 3 4 5
6 7 8 9 10
10 9 8 7 6
5 4 3 2 1
Transpose Matrix A:
1 6 10 5
2 7 9 4
3 8 8 3
4 9 7 2
5 10 6 1

The C programming language does not remember the lengths of arrays like other programming languages do. That makes working with multidimensional arrays difficult.
To pass a multidimensional array as a parameter in C, you either have to know the dimensions of the array at compile time:
#define HEIGHT 10
#define WIDTH 13
void function_prototype(int M[HEIGHT][WIDTH]) {
access M normally with M[y][x]
}
or you have to pass a single dimensional array and the lengths as parameters:
void function_prototype(int* M, int height, int width) {
access M as M[y * width + x]
}
It's troublesome, but that's the price you pay for having extremely fast array access.

Related

Sorts even numbers in ascending order and sorts odd numbers in descending order in C language [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
A function that moves the sorted at the beginning followed by the sorted odd numbers in descending order of an array. (Store it in an array, this array can be accessible at the main program)
Example:
Input: 2 3 4 5 2 1 3
Output: 2 2 4 5 3 3 1
Input: 5 -3 4 2 -11 -4 6
Output: -4 2 4 5 -3 -11
Here is my code:
#include <stdio.h>
#include<conio.h>
int sorted_even(int[], int);
int main()
{
int i,n;
printf("Enter how many elements:");
scanf("%d",&n);
int arr[n];
printf("Enter %d elements:\n", n);
for(i=0;i<n;i++)
{
scanf("\n%d",&arr[i]);
}
sorted_even(arr,n);
}
int sorted_even(int arr[], int n)
{
int arr1[n], j, k, c=0, temp, b;
int i;
for(i=0;i<n;i++)
{
if (arr[i]%2==1)
c++;
}
for(i=0;i<n-1;i++)
{
for(j=0;j<n-i-1;j++)
{
if(arr[j]>arr[j+1])
{
temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
k=0;
j=n-c;
for(i=0;i<n;i++)
{
if(arr[i]%2==0)
{
if(k<n-c)
arr1[k++]=arr[i];
}
else
{
if(j<n)
arr1[j++]=arr[i];
}
}
printf("\nresults:");
for(i=0;i<n;i++)
{
arr[i]=arr1[i];
printf("\n%d", arr[i]);
}
}
But I have some problems when it comes to sorting the Odd numbers in descending order. :'<
Unless you are doing this as part of some algorithm theory class, you probably shouldn't be inventing your own sorting algorithms. Notably you are using "bubble sort" which is the least efficient one.
If we instead write the code so that we separate the element comparison logic from the sorting algorithm, everything turns much more modular and maintainable. That's how standard C qsort works. It could be implemented as a "quick sort" algorithm, or a merge sort, we don't have to know or care how. We just provide the element comparison as a callback function passed to qsort, which will then call our function over and over during sorting.
As required by the qsort specification, our comparison function should return a number less than 0, equal to zero or larger than zero, depending on if the first object is smaller, equal or larger than the second object.
In your case, it goes like this:
#include <stdlib.h>
#include <stdio.h>
int even_asc_odd_desc (const void* p1, const void* p2)
{
const int* i1 = p1;
const int* i2 = p2;
if(*i1 & 1)
if(*i2 & 1) // both odd
return *i1 < *i2;
else // first odd, second even
return 1;
else
if(*i2 & 1) // first even, second odd
return -1;
else // both even
return *i2 < *i1;
}
int main(void)
{
int arr1[] = {2, 3, 4, 5, 2, 1, 3}; // Output: 2 2 4 5 3 3 1
int arr2[] = {5, -3, 4, 2, -11, -4, 6}; // Output: -4 2 4 6 5 -3 -11
qsort(arr1, sizeof arr1/sizeof *arr1, sizeof *arr1, even_asc_odd_desc);
qsort(arr2, sizeof arr2/sizeof *arr2, sizeof *arr2, even_asc_odd_desc);
for(size_t i=0; i<sizeof arr1/sizeof *arr1; i++)
printf("%d ", arr1[i]);
printf("\n");
for(size_t i=0; i<sizeof arr2/sizeof *arr2; i++)
printf("%d ", arr2[i]);
printf("\n");
return 0;
}
Now even if you want to write your own sorting algorithm, you can still use a comparison function like above, to separate the sorting from the comparison logic.
Just for reference, this is how you'd implement it with the same generic function template as standard C qsort:
void bubble_sort (void* base,
size_t nmemb,
size_t size,
int (*compar)(const void*, const void*))
{
for(size_t i=0; i<nmemb-1; i++)
{
for(size_t j=0; j<nmemb-i-1; j++)
{
// we can't do pointer arithmetic on void*, convert to integer type:
uintptr_t o1 = (uintptr_t)base + j*size;
uintptr_t o2 = (uintptr_t)base + (j+1)*size;
// then convert back to pointer types:
void* p1 = (void*)o1;
void* p2 = (void*)o2;
if( compar(p1, p2) > 0 ) // if *p1 > *p2
{
// swap items
unsigned char tmp[size];
memcpy(tmp, p1, size);
memcpy(p1, p2, size);
memcpy(p2, tmp, size);
}
}
}
}
Now you can replace qsort with bubble_sort in the first example and get the same result - and now we've invented a crappier generic sorting algorithm than the fast standard one already provided to us.
as i understand, you want to sort all the array in arr and then reorder them by odd and even in arr1, so you have to set the odd numbers with reverse order, start with n and then back, k and j will meet at the middle becase you count the number of odd numbers first.
this code will do the trick:
k=0;
j=n-1;
for(i=0;i<n;i++)
{
if(arr[i]%2==0)
{
arr1[k++]=arr[i];
}
else
{
arr1[j--]=arr[i];
}
}
This works as required. I initialized the variable j to 0 and inserting the odd elements in the sorted array arr to the back of the new array arr1.
k=0;
j=0;
for(i=0;i<n;i++){
if(arr[i]%2==0)
{
if(k<n-c){
arr1[k]=arr[i];
k++;
}
}
else
{
if(j<n){
arr1[n-j-1]=arr[i];
j++;
}
}
}
printf("\nresults:\n");
for(i=0;i<n;i++)
{
//arr[i]=arr1[i];
printf("%d\n", arr1[i]);
}

How many times is the function called in this C code?

This code should show how many times the Sort function is called when we have a range of array starting with l and ending with r. Note that the goal isn't showing the sorted array. So it uses mergesort but I deleted the merge step because the goal is just finding out how many times the Sort function is called.
I don't know which part of the code is wrong and why I can't get the correct answer.
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
int counter;
bool isSorted (int array[], int l, int r)
{
bool flag;
int i;
int size=l-r+1;
if (size==0 || size==1)
flag=true;
for (i=l; i<r-1 ; i++)
{
if (array[i]<array[i+1])
flag=true;
else
flag=false;
}
return flag;
}
void Sort(int A[], int l, int r) {
// Sorts [l, r)
if (!isSorted(A, l, r))
{
counter=counter+2;
int mid = (l + r) / 2;
Sort(A, l, mid);
Sort(A, mid, r);
}
}
int main()
{
int number,length,c,d,k;
scanf("%d %d", &length, &number);
int l[number],r[number];
int a[length];
for (c = 0; c < length ; c++)
scanf("%d", &a[c]);
for (d = 0; d < number ; d++)
scanf("%d %d", &l[d], &r[d]);
void TASort(int A[],int l,int r);
for(k=0; k<number ; k++)
{
counter=1;
Sort(a,l[k],r[k]);
printf("%d\n", counter);
}
return 0;
}
Two numbers in the first line o input show the number of elements in the array and the number of ranges that the user wants(Using l and r).
For Example:
Input:
8 2
34 7 11 27 2 35 32 16
1 5
3 7
Output:
5
3
You need to look at your function isSorted(). When there are three or more items of data to look at, there will be two or more comparisons. Each time you set flag you don't take into account its current value. This means that the isSorted() function will return true if the last two items it compared were sorted irrespective of whether the previous ones were.

Passing Multidimensional arrays to functions as Pointers

I have to pass two arrays ( A and B with dimensions of 5X4) to two functions called FUNCTION_1 and FUNCTION_2. Both of arrays columns and rows should be passed as POINTERS. FUNCTION_1 will take each element of A array and calculate the sum of prime factors of each element located in A( (with the help of another function called sumPrime), then it will store these sums in array B. FUNCTION_2 has to print both of A and B arrays. ( The normal numbers array, and the prime factors sums array). There are some additions in the program which are not important now but I am going to show them too in respect of clearness.
#include <stdio.h>
#include <stdlib.h>
#define ROW 5
#define COL 4
# include <math.h>
int sumPrime(int number){
int factor = 2;
int sum=0;
while(1!=number){
if(number%factor==0){
number /= factor;
sum+=factor;
factor = 2;
continue;
}
factor++;
}
return sum;
}
int FUNCTION_1(int *a[][20],int *b[][20],int row, int col){
int c,d;
for(c=0;c<row;c++){
for(d=0;d<col;d++){
b[c][d]=sumPrime(a[c][d]);
return b[c][d];
}
}
}
void FUNCTION_2(int *x[][20],int *y[][20],int rows, int cols){
printf(" \n A matrix is :\n");
int e,f;
for(e=0;e<rows;e++){
for(f=0;f<cols;f++){
printf("A[%d][%d] is %d\n",e,f,x[e][f]);
}
}
printf("\n B matrix is:\n");
for(e=0;e<rows;e++){
for(f=0;f<cols;f++){
printf("A[%d][%d] is %d\n",e,f,FUNCTION_1(x,rows,cols,y,rows,cols));
}
}
}
int main(){
int A[ROW][COL]={0};
int B[ROW][COL]={0};
int x=1;
int i;
int j;
for(i=0;i<ROW;i++){
for(j=0;j<COL;j++){
A[i][j]=x;
x=x+2;
}
}
printf("%d",A[0][0]);
return 0;
}
When trying to perform FUNCTION_1 or FUNCTION_2 I get many errors or even when defining the functions. There is no problem with defining A matrix or prime function! HELP!!
Your definition for a matrix is wrong ..
Use :
func(int* a[20] , int cols)
in this case you will have 20 rows ,
or
func(int a[][20] , int rows)
And define some macro for the columns if it is fixed value .

Function passing of multidimensional array in c

#include <stdio.h>
void spiral(int a[10][10]) {
printf("%d", a[1][3]);
}
int main() {
int r, c, j, i;
scanf("%d%d", &r, &c);
int a[r][c];
for (i = 0; i < r; i++)
for (j = 0; j < c; j++) {
scanf("%d", &a[i][j]);
}
spiral(a);
return 0;
}
When I give a 3 x 6 array
1 2 3 4 5 6
7 8 9 10 11 12
13 14 15 16 17 18
The output is 14, while it should be 10
How to fix this issue?
If you enter 3 and 6 for r and c (respectively) then the type of a is not int[10][10] (or int(*)[10] as the spiral argument really is), it's int[3][6]. The memory layout is completely different for the arrays, leading to undefined behavior.
You can solve this by passing the size along to the function, and using it in the declaration of the array:
void spiral(const size_t r, const size_t c, int (*a)[c]) { ... }
Call it like expected:
spiral(r, c, a);
As noted using int a[r][c] as argument might be easier to read and understand, but it gives a false impression that a is actually an array. It's not. The compiler treats the argument as a pointer to an array of c integers, i.e. int (*a)[c].
This makes me a little conflicted... On the one hand I'm all for making things easier to read and understand (which means it will be easier to maintain), on the other hand newbies often get it wrong and think that one can pass an array intact when in fact it decays to a pointer which can lead to misunderstandings.
A few things are wrong: in void spiral() you ask for a 2D-array of 10*10, but you do not give that. Keep that part as a variable, so only ask the type you receive and not what you want to receive and with creating a dynamic array you should always do that with malloc or calloc and free them afterwards. This might be a bit hard at first, but when you start creating bigger programs this is a must if you have a question or do not understand the pointers in the program called (*) then ask me:
#include <stdio.h>
#include <stdlib.h>
void spiral(int **a) {
printf("%d", a[1][3]);
}
int main() {
int r, c, j, i;
scanf("%d%d", &r, &c);
int **a = malloc(r * sizeof(int*));
for (i = 0; i < r; i++) {
a[i] = malloc(c * sizeof(int));
}
for (i = 0; i < r; i++) {
for (j = 0; j < c; j++) {
scanf("%d", &a[i][j]);
}
}
spiral(a);
for (i = 0; i < r; i++) {
free(a[i]);
}
free(a);
return 0;
}

How to use functions with arrays correctly

This is a small program that I wrote to add 2 square matrices.
When i input the second matrix the values of the first are altered and the result is subsequently false. It works quite well for 2x2 matrices,But not for any bigger matrix.
The algorithm works well without the use of functions.
Please help me solve this problem.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
int n;
void PrintMatrix(int P[n][n])
{
int i,j;
for(i=0;i<n;i++)
{
printf("\n");
for(j=0;j<n;j++)
{
printf("%d\t", P[i][j]);
}
}printf("\n");
}
void ReadMatrix(int P[n][n])
{
int i,j;
for(i=0;i<n;i++)
{
printf("input row %d\n", i+1);
for(j=0;j<n;j++)
{
scanf("%d", &P[i][j]);
}
}
}
void AddMatrix(int P[n][n], int Q[n][n], int Result[n][n])
{
int i,j;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
Result[i][j]=P[i][j]+Q[i][j];
}
}
}
int main()
{
int i,j;
int A[n][n];
int B[n][n];
int Sum[n][n];
printf("input matrix size:");
scanf("%d", &n);
printf("input first matrix\n");
ReadMatrix(A);
PrintMatrix(A);
printf("input second matrix\n");
ReadMatrix(B);
PrintMatrix(B);
AddMatrix(A,B,Sum);
PrintMatrix(Sum);
return 0;
}
You can define your own matrix type with a struct, such as for example:
typedef struct
{
int* data;
size_t width;
size_t height
} matrix_t;
Or if you have a modern C compiler, you can write the functions like
void func (size_t width, size_t height, int matrix[width][height])
But the struct version is probably to prefer.
EDIT
As for why your program is buggy, you must initialize n to a value. If you declare the arrays as variable-length arrays of size [n][n] after the point where you read n from the user, it should work fine.
if you run this under gdb here is something you'll find
(gdb) p A
$14 = 0x7fffffffdfb0
(gdb) p B
$15 = 0x7fffffffdfa0
irrespective of whatever "n" you choose the array base address always differ by 16 that is integer 2 x 2 matrix works
but if i Input length as 3 the program crashes. There is memory corruption.
before doing input
(gdb) x/12 A
0x7fffffffdfb0: 0 0 -255260739 52
0x7fffffffdfc0: -1 -1 -1 -1
0x7fffffffdfd0: -8272 32767 -1 -1
after input:
x/12 0x7fffffffdfb0
0x7fffffffdfb0: 1 2 3 4
0x7fffffffdfc0: 5 6 7 8
0x7fffffffdfd0: 9 32767 -1 -1
is fine as i gave values 1 2 3 4 5 6 7 8 9
but
p A
$16 = 0x7fff00000009
is this accessing it causes segmentation fault in PrintMatrix.
now if you change your program to this
int main()
{
int i,j;
printf("input matrix size:");
scanf("%d", &n);
int A[n][n];
int B[n][n];
int Sum[n][n];
your problems are solved and you are good to go

Resources