Linear Sort of a 2D Array - c

I am a newbie to C programming and was trying to prepare some sorting programs. I made the program of linear/ normal Sorting.
Now I want to make a program to sort 2D array.
i.e. If the matrix is
4 6 1
3 2 9
5 7 8
Then the result should be
1 2 3
4 5 6
7 8 9

Since you want your 2D array to be sorted row-wise, which happens to be the order in which multidimensional arrays are stored in C, you could pretend it is a 1D array and sort it that way.
Assuming you have a function void sort(int[], int size); that takes a pointer to the first element of a 1D array and its size, you could do
int a[3][3] = {{4,6,1}, {3,2,9}, {5,7,8}};
sort(&a[0][0], 9);
Naturally, this only works for true 2D arrays, not for arrays of pointers, which is how dynamically allocated 2D arrays are often implemented in C.

You can use pretty much the same function, if you are allocating the memory as a regular multi-dimensional declaration... Since multi-dimensional arrays are stored in memory row after row and each row is just a regular array.
Just pass to the function the address of the first element of the matrix (usually name_of_the_matrix[0]) and the number of elements in the matrix.
Hope I could help.

The basic idea is to sort the array based on cell ordering, so you need to have a way to get a cell based on it's order and a way to write a cell based on it's ordering.
int getCellOrder(int x, int y) {
return x*(x_width) + y;
}
int getXpos(int cellOrder) {
return cellOrder / x_width;
}
int getYpos(int cellOrder) {
return cellOrder % x_width;
}
With those two elements, you can now grab any two cell orders for your array, and the values they reference.
int valueAt(int cellOrder) {
return array[getXpos(cellOrder)][getYpos(cellOrder];
}
How you compare the orders and how you swap them now becomes a simple 1D array problem.

you can use Bubble-Sort: Wikipedia and go through the array with a for-loop.

You could also take the C++ approach and do the following while representing your matrix in 1D:
#include <vector>
#include <algorithm>
using namespace std;
int main(int arg, char **argv) {
int matrix[] = {4, 6, 1, 3, 2, 9, 5, 7, 8};
vector<int> matvec (matrix, matrix + sizeof(matrix) / sizeof(int));
sort(matvec.begin(), matvec.end());
return 0;
}

I made it like this given that you made an 2D array a[][] and the elements like me:
for(i=0;i<row;i++)
for(j=0;j<col;j++)
for(k=0;k<row;k++)
for(p=0;p<col;p++)
if(a[i][j]>a[k][p])
temp=a[i][j]; a[i][j]=a[k][p]; a[k][p]=temp;

Related

In C, is it possible to store value in the last position of the array?

i only would know how to store value in the last position of the array, with the code below:
int main(int argc, char *argv[]){
int x[2][2];
int i, j;
x[2][0] = 1;
printf("%d", x[2][2]);
}
Thanks!
The last element in your matrix is in x[1][1]; just put in this position. Your vector has only four positions indexed starting in 0 going to 1 twice (for each dimension); that is, neither x[2][0] nor x[2][2] is valid — they access out of the bounds of the array.
The first element of an array in C is numbered as 0, and when creating an array, the size inputted will represent the number of elements in the said array. Hence, the first element of an array of 2 would be labelled as 0 and the second as 1, the third(2) not being allocated.
So, for example, making an array of 4 variables:
int i[4]
Would allocate four ints int memory,
i[0]
i[1]
i[2]
i[3]
these being the valid spots of the array. Of course this applies to 2D arrays like yours.
If you wish a 3-large array(Like I suppose from your use of the array element zero and two), you simply need to, as you probably understood, declare an array with a size of [3].
Keep in mind accessing invalid spots in an array might not cause a crash of your program if it had allocated some memory at the emplacement it tried to access, sometimes yielding to funny results caused by these unexpected values.
Hope this helps.

C language - Matrix multiplication bug

I'm trying to write a code that gets a matrix A and its dimensions, a matrix B and its dimensions, and returns a matrix C such that C=AB.
It's safe to assume that the number of columns of A is equal to the number of rows of B and so C=AB is defined
This is my code:
int *matrix_multiplication(int *A,int row_A,int column_A,int *B,int row_B,int column_B)
{
int row_C,column_C,*C,i,j,k,sum=0;
row_C=row_A;
column_C=column_B;
C=(int*)malloc(row_C*column_C*sizeof(int));
for(i=0;i<row_C;i++)
{
for(j=0;j<column_C;j++)
{
for(k=0;k<column_A;k++)
sum+=(*(A+column_A*i+k))*(*(B+column_B*k+j));//A[i][k]B[k][j]
*(C+row_C*i+j)=sum;
sum=0;
}
}
return C;
}
A little explanation: I view a matrix as a single dimensional array, of size columns*rows*sizeof(int) and the given formula A[i][j]=*(A+column_A*i+j) where A is pointer to the first element of the array, and column_A is the amount of columns in "matrix" A.
My problem is that my code does not work for some inputs when row_C != column_C
For example, if A=[28,8,12;14,5,45] and B=[31;27;11] it returns C=[1216;-842150451]
Why does this happen? I can't seem to find the bug.
Try
*(C+column_C*i+j)=sum;
it might be an idea to make a function or macro for accessing matrix elements. That way similar problems in the future can be avoided. Better than that make a matrix class with method.

Sort an array based on a tuple of 4 indices in C

I have an interesting problem, which I have been struggling with for the past 2 days without a concrete solution.
I am attempting to write a program in C which takes the following input array:
1,1,5,5,
1,1,5,9,
2,2,6,2,
1,2,5,5,
1,3,6,6,
1,4,5,1,
4,1,5,6,
5,2,7,1,
1,1,6,0,
2,2,5,0,
step1: group the above array based on the 3rd column like this (bucket sort on tuple of 4 elements (i.e. each row), based on values of 3rd column:
2,2,5,5
1,1,5,9,
1,2,5,5,
1,4,5,1,
4,1,5,6,
2,2,5,0,
2,2,6,2,
1,3,6,6,
1,1,6,0,
5,2,7,1
Step 2: Finally sort the elements based on the 4th column within each bucket like this:
Final Output Array:
2,2,5,0,
1,4,5,1,
2,2,5,5,
1,2,5,5,
4,1,5,6,
1,1,5,9,
1,1,6,0,
2,2,6,2,
1,3,6,6,
5,2,7,1
The elements in the 1st and 2nd column do not play any role in the above sorting process.
I have tried various techniques, using quicksort or bucket sort followed by a subsequent quicksort. Nothing has worked out quite right.
Could anyone suggest a method of doing this in C, using appropriate data structures.
The thing is, you don't really need to do multiple sorts; you can do a single sort based on two fields of your tuple.
Just use an existing sort algorithm, but with a comparing function which looks like this:
if (val[2] != otherval[2])
return val[2] < otherval[2];
else
return val[3] < otherval[3];
This will use the third column to sort, unless the values are equal, in which case it will use the fourth.
Or if you want to do two separate sorts, FIRST sort by the fourth column, THEN by the third.
#include <stdio.h>
#include <stdlib.h>
int cmp(const void *x, const void *y){
int (*a)[4] = (int(*)[4])x;
int (*b)[4] = (int(*)[4])y;
if((*a)[2]==(*b)[2])
return (*a)[3] - (*b)[3];
else
return (*a)[2] - (*b)[2];
}
int main(void){
int data[][4] = {
{1,1,5,5},
{1,1,5,9},
{2,2,6,2},
{1,2,5,5},
{1,3,6,6},
{1,4,5,1},
{4,1,5,6},
{5,2,7,1},
{1,1,6,0},
{2,2,5,0}
};
int size = sizeof(data)/sizeof(data[0]);
int i,j;
qsort(data, size, sizeof(data[0]), cmp);
//result print
for(i=0;i<size;++i){
for(j=0;j<4;++j)
printf("%d ", data[i][j]);
printf("\n");
}
return 0;
}
This should actually be pretty simple to do. The standard qsort function takes a call back which compares two elements. Just write your callback to expect the elements to be the subarrays and compare first using the Third element. If the third elements are equal then compare using the fourth element.

Scanning values into a matrix without using [ ] C language

I have a problem. I was asked to write a program that transposes a matrix, without using []...for example, i know that if it was a one dimensional array, i could say that array[3] is the same as *(array+3)...but how do i do that with a matrix?
here's my code for scanning:
void scan_matrix(matrix mat1,int number_of_rows, int number_of_columns)
{
int row_index,column_index;
for(row_index=0;row_index<number_of_rows;row_index++)
{
printf("Enter the values of row %d\n",row_index);
for(column_index=0;column_index<number_of_columns;column_index++)
scanf("%d",WHAT GOES HERE?????);
}
}
If mat1 is a simple pointer, then this should do the job for you :
for(row_index=0;row_index<number_of_rows;row_index++)
{
printf("Enter the values of row %d\n",row_index);
for(column_index=0;column_index<number_of_columns;column_index++)
scanf("%d", (mat1 + row_index*number_of_columns + column_index));
}
The program uses the fact that matrices (2-d arrays) are in fact stored as 1-dimensional arrays in memory.
Lets take a 2d matrix :
1 2 3
4 5 6
This is stored in memory as :
1 2 3 4 5 6
So, the correct variable is accessed by using a way to map the logical positions of array elements with the actual positions. All we need is to find out the relation which turns out to be :
Pos = Row*Num_Of_Col + Col
if mat is two dimensional int array like : mat[3][3]
then scanf code would be : scanf("%d",(*(mat+row_index)+column_index));
a[3] : *(a+3)
a[3][3] : (*(a+3)+3)

Introduction to Arrays [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
when do we need to pass the size of array as a parameter
So I just started working with arrays, I have 3 functions i need to create to get me to learn.
int sumarray(int a[], int n);
// a is an array of n elements
// sumarray must return the sum of the elements
// you may assume the result is in the range
// [-2^-31, 2^31-1]
int maxarraypos(int a[], int n);
// a is an array of n elements
// maxarraypos must return the position of
// the first occurrence of the maximum
// value in a
// if there is no such value, must return 0
bool lexlt(int a[], int n, int b[], int m);
// lexicographic "less than" between an array
// a of length n and an array b of length m
// returns true if a comes before b in
// lexicographic order; false otherwise
How exactly would I create these functions?
For sumarray, I'm confused since an array stores something within a certain length. Why would need the second parameter n?
And also how would I test a function that consumes an array? I was thinking like sumarray([3], 3) .. is that right?
When passed to a function, an array decays into a pointer, which inherently stores no length. The second argument would store the number of elements in the array, so, it would look something like this:
int values[] = { 16, 13, 78, 14, 91 };
int count = sizeof(values) / sizeof(*values);
printf("sum of values: %i\n", sumarray(values, count));
printf("maximum position: %i\n", maxarraypos(values, count));
for sumarray, im confused since an array stores something within a certain length, why would need the second parameter n?
You need the second parameter to tell you how long the array is. Arrays as parameters to methods in C don't come with their length attached to them. So if you have a method that takes an array as a parameter, it can't know the length unless you also pass that to the method. That's what n is for.
And also how would i test a function that consume's an array, i was thinking like sumarray([3], 3) .. is that right ?
No. You could say
int myArray[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
and then
int sum = sumarray(myArray, 10);
To solve all of these, you'll need loop (a for loop is best, I'm sure your lecturer provided examples on how to loop over the elements of an array). Beyond that, I'm not doing your homework. Ask specific, pointed questions, and I'd be happy to consider answering them though.
im confused since an array stores something within a certain length,
why would need the second parameter n?
Because you do not know the certain length. If you do not want to change the code when you change the length of the initial array, you need to pass around n because c language generally does not provide that information.

Resources