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
Related
I got an assignment to write a program that fills an empty sudoku board and prints it out.
The tools that we have are only functions, arrays and pointers. No recursion, no search and sort algorithms to improve the time complexity.
So far I thought to use two dimension array for the board and go over every row in a nested "for" loop.
Every time I fetch a number with a random function and check a row, a column and a square (3X3), and if all of them pass then I fill the number.
My problem is that, that way it takes the code a very long time to solve, and I don't know if I'm doing it right. I didn't see a solution of my code yet, even after leaving it to run more than 5 minutes. I thought maybe somehow to use a histogram of numbers from 1-9 that maps which numbers already used to somehow change the use of fetching random numbers, but I'm not really sure how to use it and if it's even right to do so. Basically I'm stuck.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#define MATRIX_SIZE 9
#define MAX_NUM 9
void solve_sudoku(int board[MATRIX_SIZE][MATRIX_SIZE]);
void print_sudoku(int board[MATRIX_SIZE][MATRIX_SIZE]);
int rowCheck(int num, int board[][MATRIX_SIZE], int row);
int columnCheck(int num, int board[][MATRIX_SIZE], int row);
int squareCheck(int num, int board[][MATRIX_SIZE], int row, int col);
int giveNum(void);
void main()
{
srand(time(NULL));
int board[MATRIX_SIZE][MATRIX_SIZE];
/*{
0,0,0,0,0,4,0,0,0,
0,6,8,0,0,0,5,0,0,
0,2,0,0,0,0,0,7,6,
6,0,0,0,0,0,8,9,0,
0,0,5,2,6,0,0,0,0,
0,0,0,9,0,0,1,0,0,
0,0,0,0,0,7,0,5,0,
0,4,0,0,0,0,0,0,1,
0,0,0,0,5,1,4,0,0
};*/
for (int row = 0; row < MATRIX_SIZE; row++)
for (int col = 0; col < MATRIX_SIZE; col++)
board[row][col] = -1;
solve_sudoku(board);
print_sudoku(board);
}
void solve_sudoku(int board[MATRIX_SIZE][MATRIX_SIZE])
{
int rowCh, colCh, sqrCh, num, square = 0;
for (int row = 0; row < MATRIX_SIZE; row++)
{
for (int col = 0; col < MATRIX_SIZE; col++)
{
if (square > 2)
square = 0;
while(1)
{
num = giveNum();
rowCh = rowCheck(num, board, row, col);
if (!rowCh)
continue;
colCh = columnCheck(num, board, row, col);
if (!colCh)
continue;
sqrCh = squareCheck(num, board, row, col-square);
if (!sqrCh)
continue;
break;
} //while (!rowCh || !colCh || !sqrCh);
square++;
board[row][col] = num;
}
}
}
void print_sudoku(int board[MATRIX_SIZE][MATRIX_SIZE])
{
printf("Sudoku solution:\n");
for (int i = 0; i < MATRIX_SIZE; i++)
{
for (int j = 0; j < MATRIX_SIZE; j++)
printf("%d ", board[i][j]);
printf("\n");
}
}
int giveNum(void)
{
int num = rand() % MATRIX_SIZE + 1;
return num;
}
int rowCheck(int num, int board[][MATRIX_SIZE], int row)
{
for (int col = 0; col < MATRIX_SIZE; col++)
{
if (num == board[row][col])
return 0;
}
return 1;
}
int columnCheck(int num, int board[][MATRIX_SIZE], int col)
{
for (int row = 0; row < MATRIX_SIZE; row++)
{
if (num == board[row][col])
return 0;
}
return 1;
}
int squareCheck(int num, int board[][MATRIX_SIZE], int row, int col)
{
for (int i = row; i < row + sqrt(MATRIX_SIZE); i++)
for (int j = col; j < col + sqrt(MATRIX_SIZE); j++)
if (board[i][j] == num)
return 0;
return 1;
}
I strongly doubt that you will have much luck with a pure random approach. There are so many combinations so that chance of hitting a valid solution is very little. Instead you'll most likely end in a dead-lock where there is no valid number to put in current position... then you just have an endless loop.
Anyway... here is a bug:
For the squareCheck function to work, it's required that col and row identifies the upper-left corner. For col you ensure that using square but for row you don't.
In other words, your check isn't correct.
Instead of using "the square method" consider to put these lines in the start of the function:
row = row - (row % 3);
col = col - (col % 3);
There's a loop while(1) where you pick a random number and determine if it is valid in the current position.
It's quite possible to get to a dead end here.
You can have easily filled in numbers that while valid individually leave the puzzle insoluble.
You need some method of backtracking if you get 'stuck' or detecting that it will get stuck.
The 'common' approach is to hold a 9x9 matrix of sets holding a subset of 1-9 which are the untried values. When a value is set (at start) or tried (during solve) you check the constraints and remove the value being tried from its column, row and square.
Start with a 9x9 grid all cells initialised to the full range [1-9].
If you set a cell to (say) 5 remove 5 from all cells in that column, row and sub-square.
If that leaves any cell with the empty set, the puzzle is insoluble.
When solving only pick from the set of 'remaining possible values' rather than rand [1-9].
However it still may be that a trial makes the puzzle insoluble and needs to go back a cell (or more) to come forward again.
The easy way to do that would be recursion. But that's ruled out by the Exercise.
So it looks like some kind of Undo stack is required.
Here is a way to generate a random suduko.
// Check that no number 1..9 is present twice in a column
int colok(int s[][9])
{
for (int col=0; col<9; ++col)
{
for (int n=1; n<=9; ++n)
{
int cnt = 0;
for (int i=0; i<9; ++i)
{
if (s[i][col] == n)
{
if (cnt > 0) return 0;
cnt = 1;
}
}
}
}
return 1;
}
// Check that no number 1..9 is present twice in a 3x3 block
int blockok(int s[][9])
{
for (int row=0; row<9; row += 3)
{
for (int col=0; col<9; col +=3)
{
for (int n=1; n<=9; ++n)
{
int cnt = 0;
for (int i=0; i<3; ++i)
{
for (int j=0; j<3; ++j)
{
if (s[i + row][j + col] == n)
{
if (cnt > 0) return 0;
cnt = 1;
}
}
}
}
}
}
return 1;
}
void p(int s[][9])
{
for (int i=0; i<9; ++i)
{
for (int j=0; j<9; ++j)
{
printf("%d ", s[i][j]);
}
puts("");
}
}
#define MAX_LOOP 10000000
void makerow(int s[][9], int r)
{
int loops = 0;
while(1)
{
++loops;
// FY Shuffle row (this ensures that rows are always valid)
int a[] = {1,2,3,4,5,6,7,8,9};
int max = 8;
while(max)
{
int t = rand() % (max + 1);
int tmp = a[t];
a[t] = a[max];
a[max] = tmp;
--max;
}
// Save row
for (int i=0; i<9; ++i)
{
s[r][i] = a[i];
}
// Check whether it's valid
if (colok(s) && blockok(s))
{
// It's valid so stop here
break;
}
// Stop if too many loops
if (loops > MAX_LOOP)
{
puts("I'm so tired...");
exit(1);
}
}
printf("loops %d\n", loops);
}
int main(void)
{
srand((int)time(0));
int s[9][9] = { 0 };
for (int i=0; i<9; ++i)
{
printf("Make row %d\n", i);
makerow(s, i);
}
p(s);
return 0;
}
Possible output:
Make row 0
loops 1
Make row 1
loops 27
Make row 2
loops 1090
Make row 3
loops 3
Make row 4
loops 1019
Make row 5
loops 5521
Make row 6
loops 96
Make row 7
loops 66727
Make row 8
loops 498687
7 5 2 4 6 8 3 1 9
3 4 6 9 1 7 8 2 5
8 1 9 3 2 5 7 6 4
9 6 3 8 7 4 2 5 1
1 8 5 2 9 3 6 4 7
2 7 4 1 5 6 9 8 3
6 9 7 5 4 2 1 3 8
5 2 8 7 3 1 4 9 6
4 3 1 6 8 9 5 7 2
But notice... it happens that no solution can be generated.. then the output is:
Make row 0
loops 1
Make row 1
loops 37
Make row 2
loops 2957
Make row 3
loops 16
Make row 4
loops 2253
Make row 5
I'm so tired...
In order to avoid recursion you can try to navigate the solution space by levels. That requires a Queue, in which you add the next possible states from a given one (just extracted from the queue) and you mark the already visited ones (e.g. with the selected numbers) In this way you only build a single loop (no nested loops required) and you can generate all the possible solutions (but you can stop at the first that just generates a valid position)
Thanks for all of your responses. There is an update: I found a bug that made me a lot of problems, The bug was that I defined : columnCheck function that receives variable row and I called the function this way: " columnCheck(num, board, row, col); ", so the bug is that in the definition I need to give only 3 arguments, when I called the function accidently with 4 and also gave the columCheck the row instead the column. Also rowCheck was called with 4 arguments instead of 3 as defined. Can someone explain why the debugger didn't warn me about that ?
Also I changed the giveNum() function to this one:
int giveNum(void)
{
int static num = 1;
if (num > 9)
num = 1;
return num++;
}
Now it's not random but it fills the sudoku.
Since a lot of people asked the instructor how to do it, he replied that this kind of solution will be fine for now, However I will take the challenge to solve it with your suggestions.
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.
I have 2D array of size m*m with element values either 0s or 1s. Furthermore, each column of the array has a contiguous block of 1s (with 0 outside that block). The array itself is too large to be held in memory (as many as 10^6 rows), but for each column I can determine the lower bound, a, and the upper bound, b, of the 1s in that column. For a given n, I need to find out those n consecutive rows which have the maximum number of 1s. I can easily do it for smaller numbers by calculating the sum of each row one by one, and then choosing n consecutive rows whose sum comes out to be maximum, but for large numbers, it is consuming too much time. Is there any efficient way for calculating this? Perhaps using Dynamic Programming?
Here is an example code fragment showing my current approach, where successive calls to read_int() (not given here) provide the lower and upper bounds for successive columns:
long int harr[10000]={0}; //initialized to zero
for(int i=0;i<m;i++)
{
a=read_int();
b=read_int();
for(int j=a;j<=b;j++) // for finding sum of each row
harr[j]++;
}
answer=0;
for(int i=0;i<n;i++)
{
answer=answer+harr[i];
}
current=answer;
for(int i=n;i<m;i++)
{
current=current+harr[i]-harr[i-n];
if(current>answer)
{
answer=current;
}
}
For example (with m = 6 and n = 3)
Here the answer would be row 1 to row 3 with a total 1-count of 13 in those rows. (Row 2 to row 4 also maximizes the sum as there is a tie.)
Here is a different approach. Think of each pair a, b as defining an interval of the form [a,b+1). The task is to find the n consecutive indices which maximizes the sum of the parenthesis depth of the numbers in that interval. Every new a bumps the parenthesis depth at a up by 1. Every new b causes the parenthesis depth after b to go down by 1. In the first pass -- just load these parentheses depth deltas. Then one pass gets the parenthesis depths from these deltas. The following code illustrates this approach. I reduced m to 6 for testing purposes and replaced calls to the unkown read_int() by accesses to hard-wired arrays (which correspond to the example in the question):
#include <stdio.h>
int main(void){
int a,b,answer,current,lower,upper;
int n = 3;
int lower_bound[6] = {0,1,2,3,1,2};
int upper_bound[6] = {3,4,3,5,2,4};
int m = 6;
int harr[6]={0};
//load parenthesis depth-deltas (all initially 0)
for(int i=0;i<m;i++)
{
a = lower_bound[i];
b = upper_bound[i];
harr[a]++;
if(b < m-1)harr[b+1]--;
}
//determine p-depth at each point
for(int i = 1; i < m; i++){
harr[i] += harr[i-1];
}
//find optimal n-rows by sliding-window
answer = 0;
for(int i=0;i<n;i++)
{
answer = answer+harr[i];
}
current =answer;
lower = 0;
upper = n-1;
for(int i=n;i<m;i++)
{
current = current+harr[i]-harr[i-n];
if(current>answer)
{
answer = current;
lower = i-n+1;
upper = i;
}
}
printf("Max %d rows are %d to %d with a total sum of %d ones\n", n,lower,upper,answer);
return 0;
}
(Obviously, the loop which loads harr can be combined with the loop which computes answer. I kept it as two passes to better illustrate the logic of how the final harr values can be obtained from the parentheses deltas).
When this code is compiled and run its output is:
Max 3 rows are 1 to 3 with a total sum of 13 ones
I'm not sure how the following will scale for your 10^6 rows, but it manages the the trailing sum of x consecutive rows in a single pass without function call overhead. It may be worth a try. Also insure you are compiling with full optimizations so the compiler can add its 2 cents as well.
My original thought was to find some way to read x * n integers (from your m x n matrix) and in some fashion look at a population of set bits over that number of bytes. (checking the endianness) and taking either the first or last byte for each integer to check whether a bit was set. However, the logic seemed as costly as simply carrying the sum of the trailing x rows and stepping through the array while attempting to optimize the logic.
I don't have any benchmarks from your data to compare against, but perhaps this will give you another idea or two.:
#include <stdio.h>
#include <stdlib.h>
#ifndef CHAR_BIT
#define CHAR_BIT 8
#endif
#ifndef INT_MIN
#define INT_MIN -(1U << (sizeof (int) * CHAR_BIT - 1))
#endif
int main (int argc, char **argv) {
/* number of consecutive rows to sum */
size_t ncr = argc > 1 ? (size_t)atoi (argv[1]) : 3;
/* static array to test summing and row id logic, not
intended to simulate the 0's or 1's */
int a[][5] = {{1,2,3,4,5},
{2,3,4,5,6},
{3,4,5,6,7},
{4,5,6,7,8},
{3,4,5,6,7},
{0,1,2,3,4},
{1,2,3,4,5}};
int sum[ncr]; /* array holding sum on ncr rows */
int sumn = 0; /* sum of array values */
int max = INT_MIN; /* variable holding maximum sum */
size_t m, n, i, j, k, row = 0, sidx;
m = sizeof a / sizeof *a; /* matrix m x n dimensions */
n = sizeof *a / sizeof **a;
for (k = 0; k < ncr; k++) /* initialize vla values */
sum[k] = 0;
for (i = 0; i < m; i++) /* for each row */
{
sidx = i % ncr; /* index for sum array */
if (i > ncr - 1) { /* sum for ncr prior rows */
for (k = 0; k < ncr; k++)
sumn += sum[k];
/* note 'row' index assignment below is 1 greater
than actual but simplifies output loop indexes */
max = sumn > max ? row = i, sumn : max;
sum[sidx] = sumn = 0; /* zero index to be replaced and sumn */
}
for (j = 0; j < n; j++) /* compute sum for current row */
sum [sidx] += a[i][j];
}
/* output results */
printf ("\n The maximum sum for %zu consecutive rows: %d\n\n", ncr, max);
for (i = row - ncr; i < row; i++) {
printf (" row[%zu] : ", i);
for (j = 0; j < n; j++)
printf (" %d", a[i][j]);
printf ("\n");
}
return 0;
}
Example Output
$./bin/arraymaxn
The maximum sum for 3 consecutive rows: 80
row[2] : 3 4 5 6 7
row[3] : 4 5 6 7 8
row[4] : 3 4 5 6 7
$./bin/arraymaxn 4
The maximum sum for 4 consecutive rows: 100
row[1] : 2 3 4 5 6
row[2] : 3 4 5 6 7
row[3] : 4 5 6 7 8
row[4] : 3 4 5 6 7
$ ./bin/arraymaxn 2
The maximum sum for 2 consecutive rows: 55
row[2] : 3 4 5 6 7
row[3] : 4 5 6 7 8
Note: if there are multiple equivalent maximum consecutive rows (i.e. two sets of rows where the 1's add up the the same number), the first occurrence of the maximum is selected.
I'm not sure what optimizations you are choosing to compile with, but regardless which code you use, you can always try the simple hints to the compiler to inline all functions (if you have functions in your code) and fully optimize the code. Two helpful ones are:
gcc -finline-functions -Ofast
So I have made a matrix, that's formed by (NxN). And the numbers for the matrix are put in through user input into a multidimensional array. I'm using pointers and malloc. So I have to select a number in the array to then get the sum of adjacent numbers, the number is selected just by saying the position. So just saying the 3rd number in the matrix. I am a little confused on how to just select a number, I have a general idea of incrementing to get to the right position? Would this be right? And will this then make it harder or easier to then get the sum of the adjacent numbers?
Just a little confused on how to then do this with a multidimensional array, would i just turn it back into a single array?
This is how i create the matrix:
for(i = 0; i< matrixSize; i++)
{
for(j=0; j < matrixSize; j++)
{
scanf("%d", &matrixValues[i][j]);
}
}
If you mean number in a matrix as follows (example for matrixSize == 4):
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
you can just calculate indexes from number
matrixValues[number/matrixSize][number%matrixSize]
EDIT:
For case when your 2D arreay defined as
int matrixValues[matrixSize][matrixSize];
All elements allocated in memory sequentially, i.e. element matrixValues[1][0] is exact after matrixValues[0][matrixSize-1], so you can use number as shift from adress of element matrixValues[0][0], e.g.:
*(((int*)matrixValues) + number)
For your example it can be
int matrixValues[matrixSize][matrixSize];
// input as 2D array
int i, j;
for(i = 0; i< matrixSize; i++)
{
for(j=0; j < matrixSize; j++)
{
scanf("%d", &matrixValues[i][j]);
}
}
// using address of matrix as begining of array
int* fakeArray = (int*)matrixValues;
// output as 1D arrray
int n;
for(n = 0; n < matrixSize * matrixSize ; n++)
{
printf("%d ", fakeArray[n]);
}
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