Reordering the rows in a matrix in a specific order - c

I am successfully storing the calculated subsets in a 2-D array matrix in C language.Now I want to print the subsets in an order desired.
For eg.
2-D array matrix is
10 7 3 2 1
10 7 5 1
7 6 5 3 2
10 6 5 2
10 7 6
Desired Output
10 7 6
10 7 5 1
10 7 3 2 1
10 6 5 2
7 6 5 3 2
How quick sort can be applied to sort/order these rows?

As #chqrlie noted, this can be easily solved with qsort.
Depending on the way the matrix is declared (is it an array of pointers to arrays of ints? do all arrays have the same length? is it a global array of fixed size?) the code will have to do slightly different things.
So, assuming the array is a global variable and all rows have same length (padded with 0s):
MWE:
#include <stdio.h>
#include <stdlib.h>
/*
Compare 2 integers
returns:
-1 if *i1 < *i2
+1 if *i1 > *i2
0 if *i1 == *i2
*/
int intcmp(const int *i1, const int *i2)
{
return (*i2 < *i1) - (*i1 < *i2);
}
#define ROWS 5
#define COLS 5
/*
Assumes rows already sorted in descending order
NOTE: qsort calls the comparison function with pointers to elements
so this function has to be tweaked in case the matrix is an array of
pointers. In that case the function's declaration would be:
int rowcmp(int **pr1, int **pr2)
{
const int *r1 = *pr1;
const int *r2 = *pr2;
// the rest is the same
}
*/
int rowcmp(const int *r1, const int *r2)
{
int i = 0, cmp;
do {
cmp = intcmp(&r1[i], &r2[i]);
i++;
} while (i < COLS && cmp == 0);
return -cmp; /* return -cmp to sort in descending order */
}
int data[5][5] = {
{10,7,3,2,1},
{10,7,5,1,0},
{ 7,6,5,3,2},
{10,6,5,2,0},
{10,7,6,0,0}
};
void printmatrix()
{
int i, j;
for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLS; j++) {
printf("%d ", data[i][j]); /* leaves a trailing space in each row */
}
printf("\n");
}
}
int main()
{
printmatrix();
qsort(data, 5, sizeof(data[0]), (int (*)(const void *, const void *))rowcmp);
printf("\n");
printmatrix();
return 0;
}
For the most flexible solution, I would define
struct row {
size_t len;
int *elems;
};
struct matrix {
struct row *rows;
size_t nrows;
};
and change the code accordingly.
NOTE: code not thoroughly tested, use with caution ;)

First of all, are you sure that the 1 on row 3,col 5 should be there and not on the last line?
Anyway, an efficient way to achieve what you want is:
compute the frequency array
declare a new matrix
go from the highest element (10 in your case) from frequency array and put in your matrix using your desired format.
It is time-efficient because you don't use any sorting algorithm, thus you don't waste time there.
It is NOT space-efficient because you use 2 matrices and 1 array, instead of only 1 matrix as suggested in other posts, but this should not be a problem, unless you use matrices of millions of rows and columns
C code for frequency array:
int freq[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
for(int i=0; i<NO_ROWS; i++) {
for(int j=0; j<NO_COLS; j++) {
if(MATRIX[i][j]!=null && MATRIX[i][j]>0 && MATRIX[i][j]<11) {
freq[MATRIX[i][j]]++;
}
}
}
C code for computing the new matrix dimensions
(assuming you want to keep the number of rows)
OUTPUT_MATRIX[100][100] /*I declared it statically, but I would advise to make it dinamically */
/* first, compute the number columns.
To do so, we need the number of elements
(we get them by simply summing up frequency array's elements) */
int s=0;
for(int i=0; i<11; i++) {
s+=frequency[i];
}
int addOne = 0 /* boolean value to check if we will have to add one extra column for safety */
if(s % NO_ROWS) {
addOne = 1; /* division is not even, so we will have to add extra column */
}
NO_COLS = s/NO_ROWS + addOne;
Now, final part, assigning the values from frequency array to the OUTPUT_MATRIX
int k=0;
int currentNumber = 10; /* assigning starts from 10 */
for(int i=0; i<NO_ROWS; i++) {
for(int j=0; j<NO_COLS; j++) {
if(currentNumber>0) {
if(frequency[currentNumber]==0 || k>=frequency[currentNumber]) {
currentNumber--;
k=0;
}
OUTPUT_MATRIX[i][j] = frequency[currentNumber];
k++;
} else {/*here, you can assign the rest of the value with whatever you want
I will just put 0's */
OUTPUTMATRIX[i][j] = 0;
}
}
}
Hope this helps!

This is what I do in C++ to reorder a matrix:
// b is the matrix and p is an array of integer containing the desired order of rows
for(i=0; i<n; i++){
if( p[i]==i )
continue;
b[i].swap(b[p[i]]);
j = p[i]; // New row i position
// Update row i position to new one
for(int k=i+1; k<n; k++){
if( p[k] == i )
p[k] = j;
}
printRow( b[i] );
}

You need to define an array of pointers of the data type you use and then you can reorder your matrix.
for example your matrix is: arr[5][10], and you want to print line 4 before line 3:
int *[5] arr2;
arr2[0] = &arr[0][0];
arr2[1] = &arr[1][0];
arr2[2] = &arr[2][0];
arr2[3] = &arr[4][0];
arr2[4] = &arr[3][0];
in regard to how will the ordering algorithm work, i would suggest placing a header in the start of each array in the matrix which will tell you how many elements it has(basically the first element of each array can be a counter of the total elements) afterwards you can order the strings by comparing the header, and if it is equal comparing the first element and so on. this can be done in a loop that iterates as many times as there are elements in the array, when the elements are not equal, break out of the loop.
hope this helps.

Related

Rearranging rows in dynamically allocated 2D array in C

I'm currently working on a program in C where I input matrix dimensions and elements of a matrix, which is represented in memory as dynamic 2D array. Program later finds maximum of each row. Then it finds minimal maximum out of maximums of all rows.
For example,
if we have 3x3 matrix:
1 2 3
7 8 9
4 5 6
maximums are 3, 9, 6 and minimal maximum is 3. If minimal maximum is positive, program should proceed with rearranging order of rows so they follow ascending order of maximums, so the final output should be:
1 2 3
4 5 6
7 8 9
I made a dynamic array which contains values of maximums followed by row in which they were found, for example: 3 0 6 1 9 2. But I have no idea what should I do next. It crossed my mind if I somehow figure out a way to use this array with indices I made that I would be in problem if I have same maximum values in different rows, for example if matrix was:
1 2 3
4 5 6
7 8 9
1 1 6
my array would be 3 0 6 1 9 2 6 3. I would then need additional array for positions and it becomes like an inception. Maybe I could use some flag to see if I've already encountered the same number, but I generally, like algorithmically, don't know what to do. It crossed my mind to make an array and transfer values to it, but it would waste additional space... If I found a way to find order in which I would like to print rows, would I need an adress function different than one I already have? (which is, in double for loop, for current element - *(matrix+i * numOfCols+currentCol) ) I would appreciate if somebody told me am I thinking correctly about problem solution and give me some advice about this problem. Thanks in advance!
I don't know if I have understood it correctly, but what you want to do is to rearrange the matrix, arranging the rows by the greatest maximum to the least...
First, I don't think you need the dynamic array, because the maximums are already ordered, and their position on the array is enough to describe the row in which they are.
To order from maximum to minimum, I would make a loop which saved the position of the maximum and then, use it to store the correspondent row in the input matrix into the output matrix. Then, change the value of that maximum to 0 (if you include 0 in positives, then change to -1), and repeat the process until all rows have been passed to the output matrix. Here is a sketch of what it would look like:
for(k = 0; k < n_rows; ++k)
for(i = 0; i < n_rows; ++i)
if (max[i] > current_max)
current_max = max[i];
max_row = i;
for(c = 0; c < n_columns; ++c)
output_matrix[row][c] = inputmatrix[max_row][c];
max[max_row] = 0;
Array is not dynamic because we can not change the size of array, so in this case you can use double pointer, for example, int **matrix to store the value of 2D array.
The function for searching the max value of each row and the row index of each max value:
int * max_of_row(int n, int m, int **mat) {
// allocate for n row and the row index of max value
int *matrix = malloc (sizeof(int) * n*2);
for(int i = 0; i < 2*n; i++) {
matrix[i] = 0;
}
int k = 0;
for(int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if(matrix[k] < mat[i][j]) {
matrix[k] = mat[i][j];
}
}
matrix[k+1] = i;
k += 2;
}
return matrix;
}
The main function for test:
int main(int argc, char const *argv[])
{
// allocate for 4 rows
int **matrix = malloc (sizeof (int) * 4);
for (int i = 0; i < 4; i++) {
// allocate for 3 cols
matrix[i] = malloc(sizeof(int) * 3);
for(int j = 0; j < 3; j++){
matrix[i][j] = i+j;
}
}
int * mat = max_of_row(4, 3,matrix);
printf("matrix:\n");
for (int i = 0; i < 4; i++) {
for(int j = 0; j < 3; j++){
printf("%d ",matrix[i][j]);
}
printf("\n");
}
printf("max of row and positon\n");
for (int i = 0; i < 8; i++) {
printf("%d ", mat[i]);
}
printf("\nmax of row\n");
for (int i = 0; i < 8; i += 2) {
printf("%d ", mat[i]);
}
printf("\n");
return 0;
}
Output:
matrix:
0 1 2
1 2 3
2 3 4
3 4 5
max of row and positon
2 0 3 1 4 2 5 3
max of row
2 3 4 5

Deleting Elements from an Array based on their Position every 3 Elements

I created an array called elements_n which has the elements 0 to N-1 where N is 2. The below numbers are the elements of the array called elements_n:
0 1
I have another array called Arr which has the following elements:
0 1 3 1 2 4
If any of the first 3 elements of the array Arr are equal to the first element of elements_n which is 0, I would like to delete that element from the array called Arr. I then repeat the same process for the next 3 elements of the array Arr. So to explain myself better, I will use the following example:
Compare the first 3 elements of array Arr which are 0, 1, 3 to the first element of elements_n which is 0. Since Arr[0] == elements_n[0]. I delete Arr[0] from the array Arr.
Compare the next 3 elements of array Arr which are 1, 2, 4 to the second element of elements_n which is 1. Since Arr[3] == elements_n[1]. I delete Arr[3] from the array Arr. So the elements that should be left in the array Arr are:
1 3 2 4
When I implemented it myself in C programming with the code found below the end result is coming:
1 3 3 2 2 4
Rather than:
1 3 2 4
This is the code I implemented:
#include <stdio.h>
#include <stdlib.h>
#define N 2
int main() {
unsigned *elements_n = malloc(N * sizeof(unsigned));
for (int i = 0; i < N; i++) {
elements_n[i] = i; //Created an array which has the elements 0 to N-1
}
printf("\n");
unsigned Arr[6] = { 0, 1, 3, 1, 2, 4 };
unsigned position_indices[2] = { 3, 3 }; //Moving every 3 elements in the Arr array.
int count = 0;
int index = 0;
unsigned *ptr_Arr = &Arr[0];
do {
for (int i = 0; i < position_indices[count]; i++) {
if (ptr_Arr[i] == elements_n[count]) {
index = i + 1; //Index of the Arr element that has the same value as the element in the array elements_n
for (int j = index - 1; j < position_indices[count] - 1; j++) {
ptr_Arr[j] = ptr_Arr[j + 1];
}
}
}
printf("\n");
ptr_Arr += position_indices[count] - 1;
count++;
} while (count < 2);
for (int i = 0; i < 6; i++) {
printf("%d\t", Arr[i]);
}
printf("\n");
free(elements_n);
return 0;
}
You might try something like this (not tested).
#include <stdio.h>
#include <stdlib.h>
#define N 2
int main()
{
unsigned *elements_n = malloc(N * sizeof(unsigned));
for (int i = 0; i < N; i++)
{
elements_n[i] = i; //Created an array which has the elements 0 to N-1
}
unsigned Arr[6] = { 0, 1, 3, 1, 2, 4 };
int dest_index = 0;
int src_index = 0;
int count = sizeof(Arr)/sizeof(Arr[0]);
for ( ; src_index < count; src_index++)
{
int group = src_index / 3;
if (Arr[src_index] != elements_n[group])
{
Arr[dest_index++] = Arr[src_index];
}
}
for (int i = 0; i < dest_index; i++)
{
printf("%d\t", Arr[i]);
}
printf("\n");
free(elements_n);
return 0;
}
You need to keep track of how many elements you removed from the array.
My solution:
#include <stdio.h>
#include <stddef.h>
#include <assert.h>
#include <string.h>
size_t fancy_delete_3(const int elems[], size_t elemssize, int arr[], size_t arrsize)
{
assert(elems != NULL);
assert(arr != NULL);
assert(arrsize%3 == 0);
assert(elemssize*3 == arrsize);
// we need to count the removed elements, to know how much we need to shift left
size_t removed = 0;
// for each element in elems
for (size_t i = 0; i < elemssize; ++i) {
// check the three correponding elements in arr
for (size_t j = i*3; j < (i+1)*3; ++j) {
assert(j >= removed);
const size_t pos = j - removed;
// if elems[i] matches any of the corresponding element in arr
if (elems[i] == arr[pos]) {
// remove element at position pos
assert(arrsize >= pos + 1);
// I don't think this can ever overflow
memmove(&arr[pos], &arr[pos + 1], (arrsize - pos - 1) * sizeof(int));
++removed;
// array is one element shorter, so we can just decrease the array size
assert(arrsize > 0);
--arrsize;
}
}
}
// we return the new size of the array
return arrsize;
}
#define __arraycount(x) sizeof(x)/sizeof(x[0])
int main()
{
int elements_n[] = {0,1};
int arr[] = {0,1,3, 1,2,4};
size_t newsize = fancy_delete_3(elements_n, __arraycount(elements_n), arr, __arraycount(arr));
printf("arr size=%zu {", newsize);
for (size_t i = 0; i < newsize; ++i)
printf("%d,", arr[i]);
printf("}\n");
return 0;
}
You have several related problems around how you perform deletions. In the first place, it's not clear that you understand that you cannot actually delete anything from a C array. The closest you can come is to overwrite it with something else. Often, pseudo-deletion from an array is implemented by moving each of the elements following the deleted one one position forward, and reducing the logical length of the array.* You seem to have chosen this alternative, but (problem 1) you miss maintaining or updating a logical array length.
Your problem is made a bit more complicated by the fact that you logically subdivide your array into segments, and you seem not to appreciate that your segments are variable-length in that, as described, they shrink when you delete an element. This follows from the fact that deleting an element from one group does not change the assignments of elements to other groups. You do have a mechanism in position_groups that apparently serves to track the sizes of the groups, and in that sense its name seems ill-fitting. In the same way that you need to track and update the logical length of the overall array, you'll need to track and update the lengths of the groups.
Finally, you appear to have an off-by-one error here:
for (int j = index - 1; j < position_indices[count]-1; j++)
that would be clearer if position_indices were better named (see above), but recognizing that what it actually contains is the size of each group, and that index and j represent indices within the group, it follows that the boundary condition for the iteration should instead be just j < position_indices[count]. That's moot, however, because you're going to need a somewhat different approach here anyway.
Suggestion, then:
When you delete an element from a group, move up the entire tail of the array, not just the tail of the group.
In service to that, update both group size and logical array size when you perform a deletion, remembering that that affects also where each subsequent group starts.
When you examine or output the result, remember to disregard array elements past the logical end of the array.
* "Logical array size" means the number of (leading) elements that contain meaningful data. In your case, the logical array size is initially the same as the physical array size, but each time you delete an element (and therefore move up the tail) you reduce the logical size by one.
You never really "deleted" any element, you just shifted-down the
second and third elements from each 3-group. And then, when
printing, you iterated over the whole array.
Arrays are just continuous blocks of memory, so you need a
different strategy. You could traverse the original array with
two indexes, one as the general index counter and other as
the index for the shifted slot. If the current element is
different from the corresponding elements_n item, copy it to
the secondary index and increase it.
In case nothing is equal to the elements_n item, you would just
reassign the array elements to themselves. However, as soon as
one is equal you will be shifting them with the advantage of
keeping track of the new size.
Also, calculating the corresponding elements_n item is a simple
matter of dividing the current index by 3, so you don't even need
an extra variable to that.
#include <stdio.h>
#define N 2
int main()
{
unsigned elements_n[N] = { 0, 1 };
unsigned Arr[N*3] = { 0, 1, 3, 1, 2, 4 };
int i, j;
for (i = 0, j = 0; i < N*3; i++)
if (Arr[i] != elements_n[i/3])
Arr[j++] = Arr[i];
for (i = 0; i < j; i++)
printf(" %d", Arr[i]);
printf("\n");
return 0;
}

Conditional Statement for Array: Need to Store Values Not Equal to Value at Index in C

I have an integer pointer array b_members that contains something like the following values:
1 2 4
I want to find the values of b_members that are not equal to a specific value inside a loop and store them in another integer pointer array i_p.
For example, inside my loop at index 0 I want to find and store the two values in b_members not equal to 1, (i.e. 2 and 4). So for the first iteration
ip = 2 4
In the second iteration I want to store 1 and 4 in ip so
ip = 1 4
And in the third iteration I want to store 1 and 2 in ip so
ip = 1 2
I can do this in Matlab using the code below but I want to be able to do this in C.
b_members = [1 2 4];
for i = b_members
ip = b_members(b_members ~=i);
end
Heres what I have in C so far:
int *b_members;
int *i_p;
b_members = Get_b_members(B,j); // fills b_members with array like [1 2 4]
for(int i=0;i<B->Columns;++i){ // going through all of b_members
printf("%d ",b_members[i]);
// Finding b_members not equal to b_members[i]
for(int i2=0;i2<B->Columns;++i2){
if (b_members[i2] != b_members[i])
i_p = &b_members[i2];
}
} // End b_members for loop
I can't seem to get it to work the right way, i_p just keeps getting longer as the loop progresses and I only want it to contain the two integers at a time. Is there a way to do this like the Matlab code I provided above? Any help would be appreciated.
Update:
Using Saurav Sahu's suggestion this worked:
int **i_p = (int **)malloc(B->Columns * sizeof(int*));
int tmp;
for(int i=0;i<B->Columns;i++)
{
// Need to find b_members excluding b_members(i)
i_p[i] = (int *)malloc((B->Columns-1) * sizeof(int));
int idx = 0;
for(int jj=0;jj<=B->Columns;jj++)
{
if(i==jj) continue;
if(b_members[i] != b_members[jj])
{
i_p[i][idx++] = b_members[jj];
}
}
tmp = i;
}
for(int ii=0;ii<=tmp;++ii)
{
printf("\ti_p[%d] = ",ii);
for(int it=0;it<(B->Columns)-1;++it)
{
printf("%d ",i_p[ii][it]);
}
printf("\n");
}
printf("\n");
You can create pointer of integer pointers like this. Assign enough size to each integer pointers to store array_size-1 integers.
int a[] = {1, 2, 4};
int aSize = sizeof(a)/sizeof(a[0]);
int **b = (int **)malloc(aSize * sizeof(int*));;
for(int i = 0; i < aSize; i++){
b[i] = (int *)malloc((aSize-1) * sizeof(int));
int idx = 0;
for(int j = 0; j < aSize; j++){
if(i == j) continue;
if(a[i] != a[j]) {
b[i][idx++] = a[j];
}
}
}
It works perfectly.

Rearranging an array with respect to another array

I have 2 arrays, in parallel:
defenders = {1,5,7,9,12,18};
attackers = {3,10,14,15,17,18};
Both are sorted, what I am trying to do is rearrange the defending array's values so that they win more games (defender[i] > attacker[i]) but I am having issues on how to swap the values in the defenders array. So in reality we are only working with the defenders array with respect to the attackers.
I have this but if anything it isn't shifting much and Im pretty sure I'm not doing it right. Its suppose to be a brute force method.
void rearrange(int* attackers, int* defenders, int size){
int i, c, j;
int temp;
for(i = 0; i<size; i++){
c = 0;
j = 0;
if(defenders[c]<attackers[j]){
temp = defenders[c+1];
defenders[c+1] = defenders[c];
defenders[c] = temp;
c++;
j++;
}
else
c++;
j++;
}
}
Edit: I did ask this question before, but I feel as if I worded it terribly, and didn't know how to "bump" the older post.
To be honest, I didn't look at your code, since I have to wake up in less than 2.30 hours to go to work, hope you won't have hard feelings for me.. :)
I implemented the algorithm proposed by Eugene Sh. Some links you may want to read first, before digging into the code:
qsort in C
qsort and structs
shortcircuiting
My approach:
Create merged array by scanning both att and def.
Sort merged array.
Refill def with values that satisfy the ad pattern.
Complete refilling def with the remaining values (that are
defeats)*.
*Steps 3 and 4 require two passes in my approach, maybe it can get better.
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char c; // a for att and d for def
int v;
} pair;
void print(pair* array, int N);
void print_int_array(int* array, int N);
// function to be used by qsort()
int compar(const void* a, const void* b) {
pair *pair_a = (pair *)a;
pair *pair_b = (pair *)b;
if(pair_a->v == pair_b->v)
return pair_b->c - pair_a->c; // d has highest priority
return pair_a->v - pair_b->v;
}
int main(void) {
const int N = 6;
int def[] = {1, 5, 7, 9, 12, 18};
int att[] = {3, 10, 14, 15, 17, 18};
int i, j = 0;
// let's construct the merged array
pair merged_ar[2*N];
// scan the def array
for(i = 0; i < N; ++i) {
merged_ar[i].c = 'd';
merged_ar[i].v = def[i];
}
// scan the att array
for(i = N; i < 2 * N; ++i) {
merged_ar[i].c = 'a';
merged_ar[i].v = att[j++]; // watch out for the pointers
// 'merged_ar' is bigger than 'att'
}
// sort the merged array
qsort(merged_ar, 2 * N, sizeof(pair), compar);
print(merged_ar, 2 * N);
// scan the merged array
// to collect the patterns
j = 0;
// first pass to collect the patterns ad
for(i = 0; i < 2 * N; ++i) {
// if pattern found
if(merged_ar[i].c == 'a' && // first letter of pattern
i < 2 * N - 1 && // check that I am not the last element
merged_ar[i + 1].c == 'd') { // second letter of the pattern
def[j++] = merged_ar[i + 1].v; // fill-in `def` array
merged_ar[i + 1].c = 'u'; // mark that value as used
}
}
// second pass to collect the cases were 'def' loses
for(i = 0; i < 2 * N; ++i) {
// 'a' is for the 'att' and 'u' is already in 'def'
if(merged_ar[i].c == 'd') {
def[j++] = merged_ar[i].v;
}
}
print_int_array(def, N);
return 0;
}
void print_int_array(int* array, int N) {
int i;
for(i = 0; i < N; ++i) {
printf("%d ", array[i]);
}
printf("\n");
}
void print(pair* array, int N) {
int i;
for(i = 0; i < N; ++i) {
printf("%c %d\n", array[i].c, array[i].v);
}
}
Output:
gsamaras#gsamaras:~$ gcc -Wall px.c
gsamaras#gsamaras:~$ ./a.out
d 1
a 3
d 5
d 7
d 9
a 10
d 12
a 14
a 15
a 17
d 18
a 18
5 12 18 1 7 9
The problem is that you are resetting c and j to zero on each iteration of the loop. Consequently, you are only ever comparing the first value in each array.
Another problem is that you will read one past the end of the defenders array in the case that the last value of defenders array is less than last value of attackers array.
Another problem or maybe just oddity is that you are incrementing both c and j in both branches of the if-statement. If this is what you actually want, then c and j are useless and you can just use i.
I would offer you some updated code, but there is not a good enough description of what you are trying to achieve; I can only point out the problems that are apparent.

Splitting a 2D array to an array of smaller 2D arrays in C

Given:
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
I want to split the 2d array (struct MATRIX) into the an array of struct MATRIX
given a chunksize CS:
assume cs to be 2,
the answer would be
Seg[0]:
1 2
1 2
1 2
Seg[1]:
3 4
3 4
3 4
....
Seg[3]:
7 8
7 8
7 8
Here is my Matrix Struct:
typedef struct MATRIX {
int nrow;
int ncol;
int **element;
} MATRIX;
and here is the function the seperates them:
void SegmentMatrix(MATRIX input,MATRIX* segs,int Chunksize, int p) {
int i,j,r;
//Allocate segs
for (i = 0; i<p;i++)
{
CreateMatrix(&(segs[i]),input.nrow ,Chunksize,0);
}
//Now Copy the elements from input to the segs
//where seg0 takes from 0 to cs cols of a, and all their rows, and seg1 takes from cs to 2cs ...
printf("Stats:\n\t P: %d\t CS: %d\n",p,Chunksize);
for (r = 0; r<p; r++) {
for (i = 0; i<input.nrow;i++) {
for (j = r*Chunksize; j<r*Chunksize+Chunksize-1; j++) {
//I tried (&(segs[r]))->element... Doesn't work, produces wrong data
segs[r].element[i][j] = input.element[i][j];
}
}
PRINTM(segs[r]);
}
}
Note that PRINTM basically prints the matrix, it knows the limits by checking segs[r].nrow and ncol
and CreateMatrix takes the following inputs (&matrix, number of rows, number of colums, filltype) and mallocs from within.
filltype:
0- generates zeroth matrix
1- generates identity
else A[i][j] = j; for simplicity
The problem is that the if i print the matrices Segs[i], they all come down with their default value given by CreateMatrix, and not the newly added values.
CLARIFICATION:
Okay, so if you guys check that last PRINTM in SegmentMatrix function, it outputs the matrices as if the for loops didn't happen, aka, i can delete the for loops and would get the same output..
did i do something wrong in this line (taken from the SegmentMatrix)
Segs[r].element[i][j] = input.element[i][j];
I don't see why and what you are manipulating with multiplication by ChunkSize and r (which is uninitialized anyway), I'd suggest simplifying the code (rule of thumb: if it seems messy, it's too complex). All you need is a 3-dimensional array to store the array of chunks, and modulo arithmetic plus integer division to insert into the appropriate column of the appropriate chunk:
/* the variable-sized dimension of the `chunks' argument is w / chsz elements big
* (it's the number of chunks)
*/
void split(int h, int w, int mat[h][w], int chsz, int chunks[][h][chsz])
{
/* go through each row */
for (int i = 0; i < h; i++) {
/* and in each row, go through each column */
for (int j = 0; j < w; j++) {
/* and for each column, find which chunk it goes in
* (that's j / chsz), and put it into the proper row
* (which is j % chsz)
*/
chunks[j / chsz][i][j % chsz] = mat[i][j];
}
}
}
Demonstration, a. k. a. how to call it:
int main(int agrc, char *argv[])
{
const size_t w = 8;
const size_t h = 3;
const size_t c = 2;
int mat[h][w] = {
{ 1, 2, 3, 4, 5, 6, 7, 8 },
{ 1, 2, 3, 4, 5, 6, 7, 8 },
{ 1, 2, 3, 4, 5, 6, 7, 8 }
};
int chunks[w / c][h][c];
split(h, w, mat, c, chunks);
for (int i = 0; i < w / c; i++) {
for (int j = 0; j < h; j++) {
for (int k = 0; k < c; k++) {
printf("%3d ", chunks[i][j][k]);
}
printf("\n");
}
printf("\n\n");
}
return 0;
}
Question was unclear . so i thought he wanted just to know how to achieve this.
So i wrote this simple Pseudo code . Otherwise accept my apologize :
matrix[i] matrix
//matrixes total column size should be bigger big 2d array column size
first condition check: sum(matrix[i].colsize)>=big2d.colsize
//in this simple code raw sizes must be equal
second condition: for all i matrix[i].rawsize=big2d.rawsize
//if columns sizes will be equal the algorithm could be simplified , does not mean optimized
//splitting big2d into matrixes
for (int br=0;br<big2d.rawsize;br++){
i=0;//store matrix index
int previndex=0;//store offset for next matrix
for(int bc=0;bc<big2d.colsize;bc++){
matrix[i].val[bc-previndex][br]=big2d.val[bc][br]; //assign (bc,br)
if(bc-previndex==matrix[i].colsize-1){
i++; //move to next matrix;//if we not have next matrix then break;
previndex=bc+1;
}
/*if it be for equal chunks matrixes offset can be calculated this way too
matrix[bc/chunk].val[bc%chunk][br]=big2d.val[bc][br];
*/
}//loop columns
}//loop raws

Resources