Sorting 2d matrix cols and rows in C - c

Given set two - dimensional integers. The array consists of 5 rows and 10 columns.
Each value in the system is a random number between 0 and 20.
Have to write a program that performs the sorting of the array values as follows:
First there arrange the values in each column so that they are sorted in ascending order (top to bottom), then - so there can sort the columns right "comes right" by comparing pairs of values in different columns in the same row (a "comparison lexicography"): comparing two values ​​in two columns in the first row, if they are the same compared to the values in the second row, and so on, and accordingly change the order of columns (see example in the third printing of the array, below).
To display the array before sorting and after each of the two phases of the emergency.
for example :
I stuck with the sorting of the each cols. I don't get the sorting i want. I would like to get your help please.
This is my code:
#include "stdio.h"
#include "conio.h"
#include "malloc.h"
#include "stdlib.h"
#define N 5
#define M 10
#define LOW 0
#define HIGH 20
void initRandomArray(int arr[N][M]);
void printArray(int arr[N][M]);
void SortInColumn(int arr[N][M],int m);
int main()
{
int arr[N][M];
int m;
m=M;
srand((unsigned)time(NULL)); //To clear the stack of Random Number
initRandomArray(arr);
printf("Before sorting:\n");
printArray(arr);
printf("Sorting elements in each column:\n");
SortInColumn(arr,M);
system("pause");
return 0;
}
void initRandomArray(int arr[N][M])
{
int i,j;
for (i=0 ; i<N ; i++)
for (j=0 ; j<M ; j++)
{
arr[i][j]=LOW+rand()%(HIGH-LOW+1);
}
}
void printArray(int arr[N][M])
{
int i,j;
for (i=0 ; i<N ; i++)
{
for (j=0 ; j<M ; j++)
printf("%d ", arr[i][j]);
printf("\n");
}
}
void SortInColumn(int arr[][M],int m)
{
int i,j;
int temp;
for( i=m-1 ; i>=0 ; i--)
{
for(j=0; j<N-1; j++)
if (arr[i][j]>arr[i][j+1]) // compare adjacent item
{
temp=arr[i][j];
arr[i][j]=arr[i][j+1];
arr[i][j+1]=temp;
}
}
for (i=0 ; i<N ; i++)
{
for (j=0 ; j<M ; j++)
printf("%d ", arr[i][j]);
printf("\n");
}
}

This is mine, and it runs and gives the correct answer.
Basically, you did two things wrong.
you need three loops instead of two. The outer loop loops around each columns. the second loop makes sure you compare each column N-1 times since for each run you get one item in the right place. The inner loop do the adjacent comparison.
you need to change the comparison between arr[i][k] and arr[i][k+1] to arr[i][k] to arr[i+1][k]. Because you want to compare them in the same column, you hold the value k (column) unchanged and change the rows i.
void SortInColumn(int arr[][M],int m)
{
int i,j,k;
int temp;
for( k=0 ; k<m ; ++k)
{
for(j=0; j<N-1; j++)
{
for(i=0; i < N-1 - j; i++)
{
if (arr[i][k]>arr[i+1][k]) // compare adjacent item
{
temp=arr[i][k];
arr[i][k]=arr[i+1][k];
arr[i+1][k]=temp;
}
}
}
}
}
BTW, this algorithm is very bad in performance in general. You may want to try something else.

Let's look at your SortInColum function. I've changed the formatting to get a better understanding of what's going on, and renamed some variables.
void SortInColumn(int arr[][M],int m)
{
int row,col;
int temp;
for( row=m-1 ; row>=0 ; row--) // foreach row
{
for(col=0; col<N-1; col++) { // foreach column
if (arr[row][col]>arr[row][col+1]) { // comparing adjacent entries
// in different cols? Why?
temp=arr[row][col];
arr[row][col]=arr[row][col+1];
arr[row][j+1]=temp;
}
}
printArray(arr);
}
This function (given some changes) will sorts a single column, you can then call this for each column. Hopefully this gives you a good starting point.

Related

create a matrix with specific conditions

I would like to create a matrix with these specifics
text of exercise
write a program that reads a number k > 0 and a permutation of the first K numbers (from 0 to k-1) that does not fix any element and produce (printing on consecutive lines) permutations p0, . . . , ph such that (1) p0 is permutation given in input; (2) fro every i > 0, pi is the smallest permutation of K cthat does not fix any element and does not collide with any other permutation from p0 and pi−1. We say that 2 permutations p1, p2 ok
K collides if exists and index i from 1 to k such that p1(i) = p2(i).
my ideas i wanted to create a k*k matrix amd the first row will be the imput of a vector i will declare. I tought to fill the matrix in these way : let's take a specific element v[i][j]
v[i][j]is in the matrix if 1)v[k][j] from k =0,...,i-1 is different from v[i][j],1)v[i][k] from k =0,...,i-1 is different from v[i][j],v[i][j] is different from i , and from the remaining possibilities for v[i][j] it is the minimum from the remainin number 0,...k-1
code implementations
#include <stdio.h>
#include <stdlib.h>
#define N 50
typedef int matrix[N][N];
int min(int vector[],int n)
{
int i;
int p=0;
int min=vector[0];
for(i=0; i<n;i++)
{
if (vector[i]<=min)
{
min=vector[i];
p=i;
}
}
return min;
}
int main()
{
int k;
printf("\n insert a number ");
scanf("%d",&k);
int v[k][k];//creation of matrix I wanted
int input[k];//first row
int arrayindex[k]={0};// array from 0 to k
for(int u=0; u<k;u++)
{
arrayindex[u]=u;
}
printf("insert component of vector:");
for(int l=0;l<k;l++)
{
printf("input[%d]= ",l);
scanf("%d",&input[l]);
}
//print vector
for(int l=0;l<k;l++)
{
printf("%d",input[l]);
}
printf("\n\n");
// copy first row
for(int j=0;j<k;j++)
{
v[0][j]=input[j];
}
//printf of first row
for(int j=0;j<k;j++)
{
printf("\nv[0][%d]=%d ",j,v[0][j]);
}
//try to fill matrix
for(int i=1; i<k;i++)
{
for(int j=0;j<k;j++)
{
if (j=0){
v[i][j]!=v[i-1][j];
v[i][j]!=j;
v[i][j]=min(arrayindex,k);}
if(j!=0)
v[i][j]!=v[i-1][j];
v[i][j]!=v[i][j-1];
v[i][j]!=j;
v[i][j]=min(arrayindex,k);
}
}
//print of matrix
printf("\n the matrix is:\n ");
for(int i=0; i<k;i++)
{ printf("\n");
for(int j=0;j<k;j++)
{
printf("%d",v[i][j]);
}
}
return 0;
}
the problem in this code is in the section called try to fill matrix . When I compile nothing appear on the screen .Where is the problem ? is at least idea correct?

Why does my Matrix not return any value to the screen?

I have been trying to solve a problem, in which the query is:
Replace each element of the main diagonal with the sum of all the elements above it (in the same column) and located right from it (in the same row)
Replace each element of the opposite diagonal with the sum of all the elements below it (in the same column) and located left from it (in the same row)
My problem: I am not sure why the program doesn't show anything after the input is done
Reading the matrix
#include <stdio.h>
int main(){
int i,j,m,k,a[100][100],new_mat[100][100];
scanf("%d%d",&m,&k); //m=rows, k=columns
for (i = 0 ; i < m ; i++)
for (j = 0 ; j < k ; j++)
scanf("%d", &a[i][j]);
// INITIAL solution, however it only covered only the first closest elements to it, rather than the sum of ALL the elements below and upwards
/*
for(i=0;i<m;i++)
{
for(j=0;j<k;j++)
{
if(i==j)
if(j+1<k && i-1>=0)
{a[i][j]+=a[i][j+1]+a[i-1][j];}
if(i+j==m-1)
if(j-1>=0 && i+1<k)
{a[i][j]=a[i][j-1]+a[i+1][j];}
}
}
*/
So, I tried to reach all the remaining elements with an additional for cycle
for(i=0;i<m;i++)
{
for(j=0;j<k;j++)
{
if(i==j)
for(;j+1<k,i-1>=0;j+1,i-1)
{
a[i][j]+=a[i][j+1]+a[i-1][j];
}
if(i+j==m-1)
for(;j-1>=0,i+1<k;j-1,i+1)
{
a[i][j]=a[i][j-1]+a[i+1][j];}
}
}
And then printing the result:
for (i=0; i<m; i++)
for(j=0; j<k; j++)
printf("%d ", a[i][j]);
printf("\n");
return 0;}
However, upon entering the matrix, nothing occurs and a value is not returned to the screen
I didn't deeply inspect the code to see if it does what you want it to do. I just looked in General.
First: Conventions. Please add brackets around the for. It will be easier to review the code.
if(i+j==m-1)
{
for(;j-1>=0,i+1<k;j-1,i+1)
...
}
Second: Both loops run forever, since you don't change j and i!
Did you mean?
for(;j-1>=0,i+1<k;j--,i++)
Third: You really should learn to work with a debugger. Using proper debugger you would have found the problem in no time.

Array of structure changes the contents itself

I am currently working on a simple code to store and display top-right triangular matrix. Well, everything was fine till I tried to input 4x4 matrix structure and gave the input. The first array of structure's (called a) last value changed although I did not put any code to change ANY of the values in a. It happens in the mReorder() function. Then I tried some try-and-errors find out the problem in the 3rd row of mReorder() function. I wonder why and how to solve it.
Here is my complete code:
#include<stdio.h>
//CMO fashion
typedef struct
{
int row;
int col;
int val;
}term;
#define MAX_TERMS 10
term a[MAX_TERMS], b[MAX_TERMS];
void mReorder(void);
int main()
{
int n, i, j;
printf("Enter the number of rows: ");
scanf("%d", &n);
if (n<1 || n>MAX_TERMS)
{
printf("\nInvalid number of rows!!");
exit(0);
}
i=nCount(n);
mRead(n,i);
for (j=0; j<i+1; j++) printf("\n%d\t%d\t%d", a[j].col, a[j].row, a[j].val);
mReorder();
for (j=0; j<i+1; j++) printf("\n%d\t%d\t%d", a[j].col, a[j].row, a[j].val);
printf("\n");
for (j=0; j<i+1; j++) printf("\n%d\t%d\t%d", b[j].col, b[j].row, b[j].val);
mDisplay();
return 0;
}
void mReorder(void)
{
int i, j, k, m=1;
b[0].col=a[0].col;
b[0].row=a[0].row;
b[0].val=a[0].val;
for(i=0; i<a[0].col; i++)
for (j=1; j<=a[0].val; j++)
if (a[j].row==i)
{
b[m].col=a[j].col;
b[m].row=a[j].row;
b[m].val=a[j].val;
m++;
}
}
void mDisplay(void)
{
int i, j, k, m=1;
printf("\nThe resulting matrix is:\n");
for (i=0; i<b[0].col; i++)
{
//printf("\na");
for (k=0; k<i; k++) printf("%5c", '-');
for (j=i; j<b[0].col; j++)
{
printf("%5d", b[m].val);
m++;
}
printf("\n");
}
}
void mRead(int n, int x)
{
int i, j, m=1, val;
printf("\nEnter %d elements of the matrix: \n", x);
a[0].row=a[0].col=n;
a[0].val=x;
for (i=0; i<n; i++)
{
for (j=0; j<=i; j++)
{
scanf("%d", &val);
a[m].row=j;
a[m].col=i;
a[m].val=val;
m++;
}
}
}
int nCount(int n)
{
if (n==1)
return 1;
return (n+nCount(n-1));
}
Can you explain what's going on here?
You allocate enough space for 10 term items, but nCount(4) returns 10, and nCount(5) returns 15, etc. If you specify a value bigger than 4, you overflow your array boundaries, leading to undefined behaviour — which is something to be avoided at all costs. In practice, one of your two arrays tramples over the other, but what happens when you access the other array out of bounds is entirely up to the compiler. It may appear to work; it may crash horribly; it may corrupt other data structures.
Nominally, since you allocate 10 elements in the arrays a and b, you should be OK with the 4x4 data, but in mRead(), you set m = 1 to start with, so you end up writing to a[10] in the last iteration of the loop, which is outside the bounds of the array. Remember, C arrays are indexed from 0, so an array defined as SomeType array[N]; has elements from array[0] to array[N-1].
Note that you can rewrite nCount() as a simple (non-recursive) function:
static inline int nCount(int n) { return (n + 1) * n / 2; }
(which would need to appear before it is called, of course). Or, if you're stuck using an archaic compiler that doesn't support C99 or C11, drop the inline keyword.

Incrementing a Pointer to an Array within a structure

I'm having a bit of trouble doing this and have searched High and low on the internet for help, but to no avail.
I'm basically trying to create a random matrix and print it out, I have a function double random() which works and has been tested and I have defined a structure as follows:
typedef struct matrep {
unsigned rows, columns;
double *data;
} MATRIX;
for which I have allocated memory properly, I use this and my random function to create a random matrix but what happens is the pointer never moves,
MATRIX *rand_matrix( MATRIX *mat )
{
for ( int i=0; i < mat->rows; i++ )
{
for ( int j=0; j < mat->columns; j++ )
{
*(mat->data) = random() ;
}
}
return mat ;
}
I know it never moves because when I print out the matrix using this function
void print_matrix(MATRIX *mat )
{
int i, j ;
if ( (mat->data)==0 || (mat->rows)==0 || (mat->columns)==0 )
{
printf("Empty matrix\n" );
return ;
}
printf( "\n\nMatrix of dimensions %d x %d\n\n", mat->rows, mat->columns) ;
for ( i=0; i < mat->rows; i++ )
{
for ( j=0; j < mat->columns; j++ )
{
printf("\t%1.2lf", *(mat->data) );
}
printf("\n") ;
}
}
and exchange random in the matrix above with 'j' it ends up printing out a matrix with the correct number of rows and collumns but each value is equal to the biggest value of j.
Basically what I was hoping you could help me with is figuring out how to increment my *(mat->data) pointer. I heard something about when you call the arrow operator it increments automatically but it doesnt seem to be working and when i try *(mat->data)++ I get a nice big error.
Any help would be great thanks a million.
You don't actually want to change mat->data; you need it to continue to point at your properly-allocated memory. Instead, you need to change this:
*(mat->data) = random() ;
to something like this:
mat->data[i * mat->columns + j] = random() ;
(to refer to the i * mat->columns + jth double in the memory-block pointed to by mat->data), and this:
printf("\t%1.2lf", *(mat->data) );
to something like this:
printf("\t%1.2lf", mat->data[i * mat->columns + j]);
(similarly).
I heard something about when you call the arrow operator it increments automatically […]
This is not true, and I can't even think of anything similar that you might have heard, sorry.
Edited to add: Another approach, if you prefer, is to write something like this:
MATRIX *rand_matrix( MATRIX *mat )
{
double *pTmp = mat->data;
for ( int i=0; i < mat->rows; i++ )
{
for ( int j=0; j < mat->columns; j++ )
{
*(pTmp++) = random() ;
}
}
return mat ;
}
which increments a pointer pTmp over all the elements. I don't know which approach is more clear. But either way, I don't think it's a good idea to modify mat->data.
You should do mat->data++. (mat->data)++ is evaluating the value of mat->data and trying to increment it which is not possible.
Here: `printf("\t%1.2lf", *(mat->data) );' you're always pointing at the same memory.
You can use the [] operator to index and dereference a pointer, for example:
(mat->data)[2]
Basically for storing a matrix using array, you need to allocate memory which closely mimics the 2D matrix, i.e. each and every matrix (or array) element should be accessed uniquely using different value for rows into columns.
You can do that in C in many ways. But the following is one of the most common way of doing the same. This lacks the de-allocation i.e. free(). Please try and do that yourself and we are here if you need any help!
NOTE: I can see multiple changes should be done in you code.. and so I'm attempting to provide a generic guidelines and reference as an answer!
#include <stdio.h>
#include <stdlib.h>
int main()
{
int row, column;
int **matrix;
int i, j, val;
printf("Enter rows: ");
scanf("%d", &row);
printf("Enter columns: ");
scanf("%d", &column);
matrix = (int **) malloc (sizeof(int *) * row);
for (i=0 ; i<row ; i++)
matrix[i] = (int *) malloc (sizeof(int) * column);
val=1;
for (i=0 ; i<row ; i++) {
for (j=0 ; j<column; j++) {
matrix[i][j] = val++;
}
}
for (i=0 ; i<row ; i++) {
for (j=0 ; j<column; j++) {
printf("%3d ", matrix[i][j]);
}
printf("\n");
}
return 0;
}

Not giving the right output

The program should create a 2D table 8*8 which consists o random number<3
it should print that table.
Another task is to translate this table into another
For Example
120
210
111
The number in the center should be changed to the sum of all numbers around it 1+2+0+2+0+1+1+1=8
and that should be done for everything;
then the program should be printed
if there are any numbers larger than 9 it shoul be translated to hexadecimal.....
I didn't do the hexadecimal yet. but it is still not working ....
#include <stdio.h>
#include <stdlib.h>
#define cols 8
#define rows 8
void printA(int A[][cols]);
void printC(char C[][cols]);
void SumThemUp(int A[][cols], char C[][cols]);
int main()
{
srand(time(NULL));
int A[rows][cols];
char C[rows][cols];
int i, j;
for(i=0; i<rows; i++)
for(j=0; j<cols; j++)
A[i][j]=rand()%3;
printA(A);
SumThemUp(A,C);
printC(C);
return 0;
}
void printA(int A[][cols])
{ int i, j;
for(i=0;i<rows;i++)
{for(j=0;j<cols; j++)
{printf("%d ", A[i][j]);}
printf("\n");}
return ;
}
void printC(char C[][cols])
{
int i, j;
for(i=0;i<rows;i++)
{for(j=0;j<cols; j++)
{printf("%ch ", C[i][j]);}
printf("\n");}
return ;
}
void SumThemUp(int A[][cols], char C[][cols])
{
int i,j;
for(i=0;i<rows;i++)
{for(j=0;j<cols; j++)
C[i][j]=0;}
for(i=0;i<rows;i++)
{for(j=0;j<cols; j++)
A[i][j]=C[i++][j];
}
for(j=0;j<cols; j++)
{for(i=0;i<rows;i++)
C[i][j]+=A[i][j++];
}return;
}
So - I'm not entirely sure I know what you want the output to be -- but there are several problems with what you have:
0: For your arrays, the names should describe what the array actually holds, A and C are quite ambiguous.
1: Use { } for scoping, and put the { } on their own lines. (Maybe it just pasted poorly in Stack Overflow)
2: You have a set of loops which basically sets everything in C to 0:
for(i=0;i<rows;i++)
{
for(j=0;j<cols; j++)
{
C[i][j]=0;
}
}
Then immediately after that you have:
for(i=0;i<rows;i++)
{
for(j=0;j<cols; j++)
{
A[i][j]=C[i++][j]; // <--- problem here
}
}
So after that, both A and C are full of all 0s. On top of that, you have i++ inline when accessing columns in C. This actually changes the value that your for loop is using, so i is getting incremented for every row and every column. Presumably you want:
A[i][j]=C[i+1][j];
3: You have a similar problem here:
for(j=0;j<cols; j++)
{
for(i=0;i<rows;i++)
{
C[i][j]+=A[i][j++]; // Presumably you want j+1
}
}
4: Why are you using a char array for C? If it's holding the sum of integers it should probably be declared int. If this was your idea of printing the ints as hex (or just plain ints), it would be easier to simply use printf to output the ints as hex:
// use %d to print the integer "normally" (base 10)
// use %x if you want a hex value with lowercase letters
// use %X if you want a hex value with capital letters
printf("125 as hex is: 0x%x", 125); // 0x7d
I hope that points you in the right direction.
-- Dan
Do I understand correctly, that given matrix A, you want to get matrix C in SumThemUp, where each cell in C is a sum of its adjacent cells? In that case, these lines look suspicious as you modify the loop counters
A[i][j]=C[i++][j];
and
C[i][j]+=A[i][j++];
.
Anyway, a simple example, how I would do the summing part.
NB! Note that I use int type for matrix C. Given that you want to convert it to hex and you happend to have values 3 in all adjacent cells somewhere, you get decimal value of 3 * 8 = 24, which requires more than one character to represent. Thus, you should convert to hex during printing. (I understand that char can contain intergral values up to 255 also, but for the sake of consistency)
void SumThemUp(int A[][cols], int C[][cols]) {
int i, j, di, dj, i2, j2;
// iterate through all the rows
for (i=0 ; i<rows ; ++i) {
for (j=0 ; j<cols ; ++j) {
// initialize the cell to zero
C[i][j] = 0;
// iterate over nearby cells
for (di=-1 ; di<=1 ; ++di) {
for (dj=-1 ; dj<=1 ; ++dj) {
// do not count in the center
if (di == 0 && dj == 0) {
continue;
}
// make sure, we do not try to count in cells
// outside the matrix
i2 = i + di;
j2 = j + di;
if (i2 < 0 || j2 < 0 || i2 >= rows || j2 >= cols) {
continue;
}
// append the score here
C[i][j] += A[i2][j2];
}
}
}
}
}
Also, I did not test this code, so it may contain mistakes, but maybe it helps you finishing your summing part.
NB! And take note of comments of #Dan.

Resources