I try to find all the sub-symmetric matrix in one big matrix but I only get some of the sub-symmetric matrix and some of them are incorrect.
In my function I found all the sub-matrix and try to send all the square sub-matrix to function that check if the sub-matrix is symmetric, If the sub-matrix is symmetric I print the matrix.
main -
int main() {
int matrix[][8] = {{1, 2, 0, 3, 2, 1, 0, 9},
{2, 3, 4, 1, 2, 3, 4, 5},
{3, 4, 6, 2, 5, 6, 7, 86},
{9, 5, 8, 3, 6, 8, 9, 8},
{6, 7, 1, 4, 7, 9, 1, 9}};
findSubMatrix(matrix, 5, 8);
return 0;
}
findSubMatrix -
void findSubMatrix(int matrix[][8], int rows, int cols) {
for (int i = 0; i <= cols; i++) {
for (int j = i; j <= cols; j++) {
for (int m = 0; m <= rows; m++) {
for (int n = m; n <= rows; n++) {
if (n - m == j - i && n - m > 0) {
if (isSymmetric(matrix, i, j, m, n) == 1) {
for (int k = m; k <= n; k++) {
for (int l = i; l <= j; l++) {
printf("%d ", matrix[k][l]);
}
printf("\n");
}
printf("\n");
}
}
}
}
}
}
}
isSymmetric -
int isSymmetric(int matrix[][8], int rowStart, int rowEnd, int colStart, int colEnd) {
for (int i = colStart; i < colEnd; i++) {
for (int j = rowStart; j < rowEnd; j++) {
if (matrix[j][i] != matrix[i][j]) {
return -1;
}
}
}
return 1;
}
I appreciate any help Thanks.
All the sub-matrices, whether are they beeing tested or printed, should be square, so I'd use a different signature than OP's. Take for example this helper function which prints out a sub-matrix, given a bigger matrix passed with VLA notation, a starting point (indices of the top left corner) and a size:
void print_submatrix(int cols, int m[][cols],
int first_row, int first_col, int n)
{
for (int r = 0; r < n; ++r) {
for (int c = 0; c < n; ++c) {
printf("%3d", m[first_row + r][first_col + c]);
}
putchar('\n');
}
putchar('\n');
}
This should help us finding the correct formulas to evaluate the indices in the function that checks symmetry.
int is_symmetric(int cols, int matrix[][cols],
int first_row, int first_col, int n)
{
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
// ^^^^^^^^^ I'll loop only through half the sub-matrix
if ( matrix[first_row + i][first_col + j]
!= matrix[first_row + j][first_col + i] ) {
// ^^^^^^^^^^^^^ ^^^^^^^^^^^^^
// Note that the starting point (top left corner) is fixed,
// while the offset is changing
return 0;
}
}
}
return 1;
}
The outer loops could be rewritten too
void find_sym_submatrices(int rows, int cols, int matrix[][cols])
{
// For every possible top left corner...
for (int i = 0, mi = rows; i < rows; ++i, --mi) {
for (int j = 0, mj = cols; j < cols; j++, --mj) {
// For every possible square matrix (which fits in size).
const int m = mj < mi ? mj : mi;
for (int n = 2; n <= m; ++n) {
if (is_symmetric(cols, matrix, i, j, n) == 1) {
print_submatrix(cols, matrix, i, j, n);
}
else {
break; // Yeap, there's no need to check the bigger ones.
}
}
}
}
}
Live, here.
Related
I need help with code for sorting matrix by sum of columns.
On this site there is already a similar program with sorting by sum of rows.I copied that code and tried to adapt it for columns and it doesn't work.
And one more question:I don't understand the operation in function sum.
If someone could help me with this.
Thank you.
#include<stdio.h>
int sum(int *row, int size) {
int s = 0;
for (size--; size >= 0; size--) s += row[size];
return s;
}
int main() {
int matrix[3][4] = {{1, 2, 3, 4},
{9, 10, 11, 12},
{5, 6, 7, 8}};
int tmp;
printf("Before:\n");
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
printf("%d ", matrix[i][j]);
}
printf("\n");
}
// Bubble sort.
for (int i = 0; i < 2; i++) {
for (int j = i + 1; j < 3; j++) {
// Comparing row value.
if (sum(matrix[i], 4) > sum(matrix[j], 4)) {
// Swapping.
for (int k = 0; k < 4; k++) {
tmp = matrix[i][k];
matrix[i][k] = matrix[j][k];
matrix[j][k] = tmp;
}
}
}
}
printf("After:\n");
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
printf("%d ", matrix[i][j]);
}
printf("\n");
}
return 0;
}
Here we are given a martix and we have to find out whether the matrix is symmetrix or not. I want to optimise it using array pointer or passsing by reference or you can suggest better approach , which uses multiple concepts, and please provide an explanation , it would be helpful.
I am learning arrays so, that why I am asking you to use multiple concepts , I want to see if there is a better approach
#include <stdio.h>
#include <stdlib.h>
void swap(int arr[3][3], int i, int j)
{
int temp;
temp = arr[i][j];
arr[i][j] = arr[j][i];
arr[j][i] = temp;
}
void check(int arr[3][3], int i, int j)
{
static int count = 0;
if (arr[i][j] == arr[j][i])
{
count++;
if (count == 9)
{
printf("matrix is symmetric");
}
}
}
int main()
{
int arr[3][3] = {1, 3, 3,
3, 1, 5,
3, 5, 5};
int i, j;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%d\t", arr[i][j]);
}
printf("\n");
}
for (int i = 0; i < 3; i++)
{
for (int j = i + 1; j < 3; j++)
{
swap(arr, i, j);
}
printf("\n");
}
printf("THE TRANSPOSE MATRIX IS \n");
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%d\t", arr[i][j]);
}
printf("\n");
}
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
check(arr, i, j);
if (arr[i][j] != arr[j][i])
{
printf("matrix is non-symmetric");
exit(0);
}
}
}
}
To find symmetric matrix simply use the following code:
#include <stdio.h>
#define dim 4
int main()
{
int i=0;
int arr[dim][dim]= {1, 3, 2, 3,
3, 1, 5, 4,
2, 5, 5, 16,
3, 4, 16, 7};
int isSymmetric = 1;
while (isSymmetric && i<dim)
{
for (int j = i; j < dim; j++)
{
if(arr[i][j]!=arr[j][i]) {
isSymmetric = 0;
break;
}
}
i++;
}
isSymmetric==1?printf("Symmetric"):printf("notSymmetric");
return 0;
}
The complexity of this algorithm at most is O(N/2) when N is the number of elements.
#include <stdio.h>
int size;
void SelectionSort(int a[], int size) {
int i, j, t, min, b[] = { 0,0,0,0,0,0,0,0 };
printf("\nelements to sort : ");
for (t = 0; t < size; t++) printf("%d ", a[t]);
printf("\n\n<<<<<<<<<<<<<<<<< selection sort >>>>>>>>>>>>\n");
for (i = 0; i < size - 1; i++) {
min = i;
for (j = i + 1; j < size; j++) {
if (a[j] < a[min]) min = j;
}
b[i] = a[min];
printf("\nA ARRAY %d : ", i + 1);
for (t = 0; t < size; t++) printf("%3d", a[t]);
printf("\nB ARRAY %d : ", i + 1);
for (t = 0; t < size; t++) printf("%3d", b[t]);
}
}
void main() {
int list[8] = { 69, 10, 30, 2, 16, 8, 31, 22 };
size = 8;
SelectionSort(list, size);
getchar();
}
the issue is that whenever the comparing is done the number 2 is copied in the array
what should i do to fix this?
Each step of the selection sort needs to
Identify the least element in the subarray
Remove the element
Place it at the front
Your code is skipping step 2. So it keeps finding the 2 until i increments past it.
Instead of copying into a different array b, swap the lowest element with a[i].
t = a[min];
a[min] = a[i];
a[i] = t;
BTW, it would be helpful in this sort of question to show us the output so potential answerers don't need to compile and run the program themselves.
Here is a modification of the usual selection sort, that takes duplicates into account.
In each inner loop, the whole array is read. Only values larger than the preceding minimum (lmin) are considered, and values equal to the current accepted minimum (min) are counted (nmin is the count). Then, the array b is updated with nmin values equal to min. The first loop is a special case as there is no preceding minimum.
#include <stdio.h>
void selection_sort(int n, int a[n], int b[n]) {
int j, k, lmin, min, nmin, first;
min = a[0];
nmin = 1;
for (j = 1; j < n; j++) {
if (a[j] == min) {
nmin++;
} else if (a[j] < min) {
min = a[j];
nmin = 1;
}
}
for (k = 0; nmin > 0; nmin--) {
b[k++] = min;
}
while (k < n) {
lmin = min;
first = 1;
for (j = 0; j < n; j++) {
if (a[j] > lmin) {
if (first) {
first = 0;
min = a[j];
nmin = 1;
} else if (a[j] == min) {
nmin++;
} else if (a[j] < min) {
min = a[j];
nmin = 1;
}
}
}
for ( ; nmin > 0; nmin--) {
b[k++] = min;
}
}
}
#define N 20
int main(void) {
int a[] = {2, 5, 9, 8, 4, 7, 1, 7, 5, 0, 3, 8, 3, 3, 6, 1, 8, 0, 2, 8};
int b[N];
selection_sort(N, a, b);
for (int i = 0; i < N; i++) {
printf("%d ", a[i]);
}
printf("\n");
for (int i = 0; i < N; i++) {
printf("%d ", b[i]);
}
printf("\n");
return 0;
}
The purpose of the boolean first is to detect the first accepted current minimum (that is, the first value that is larger than lmin).
Another way would be to set min = INT_MAX before the beginning of the inner loop, where INT_MAX is the maximum int value (defined in limits.h): we know lmin < INT_MAX, otherwise we would already have exited the function. Here is this variant:
#include <stdio.h>
#include <limits.h>
void selection_sort(int n, int a[n], int b[n]) {
int j, k, lmin, min, nmin;
min = a[0];
nmin = 1;
for (j = 1; j < n; j++) {
if (a[j] == min) {
nmin++;
} else if (a[j] < min) {
min = a[j];
nmin = 1;
}
}
for (k = 0; nmin > 0; nmin--) {
b[k++] = min;
}
while (k < n) {
lmin = min;
min = INT_MAX;
nmin = 0;
for (j = 0; j < n; j++) {
if (a[j] > lmin) {
if (a[j] < min) {
min = a[j];
nmin = 1;
} else if (a[j] == min) {
nmin++;
}
}
}
for ( ; nmin > 0; nmin--) {
b[k++] = min;
}
}
}
#define N 20
int main(void) {
int a[] = {2, 5, 9, 8, 4, 7, 1, 7, 5, 0, 3, 8, 3, 3, 6, 1, 8, 0, 2, 8};
int b[N];
selection_sort(N, a, b);
for (int i = 0; i < N; i++) {
printf("%d ", a[i]);
}
printf("\n");
for (int i = 0; i < N; i++) {
printf("%d ", b[i]);
}
printf("\n");
return 0;
}
Note that in this version, nmin is set to zero before the inner loop: it doesn't matter if there are values smaller than INT_MAX. But if all remaining values are equal to INT_MAX, we are going to count them with nmin++, so we must start at zero.
I have this matrix in C.
[1,2,3,4]
[5,6,7,8]
[9,10,11,12]
[13,14,15,16]
n x n, squared matrix.
I need to split this into four matrices:
[1,2] [3,4] [9,10] [11,12]
[5,6] [7,8] [13,14] [15,16]
This will be represented inside an array like this:
array[16] = [1,2,5,6,3,4,7,8,9,10,13,14,11,12,15,16]
So far, I've done this:
int i,j;
int k = 0;
for(i = 0; i < 2; i++ )
{
for(j = 0; j < 2; j++)
{
array[k] = matrix[i][j];
k++;
}
}
for(i = 0; i < 2; i++ )
{
for(j = 2; j < 4; j++)
{
array[k] = matrix[i][j];
k++;
}
}
for(i = 2; i < 4; i++ )
{
for(j = 0; j < 2; j++)
{
array[k] = matrix[i][j];
k++;
}
}
for(i=2;i<4;i++)
{
for(j=2;j<4;j++)
{
array[k] = matrix[i][j];
k++;
}
}
As you can see, I've done 4 double for this, but, is there a dynamic way to do this? If I got a bigger matrix, like 8 x 8, how to do this? The split if bigger is the same as the example.
You should see the pattern of the routines you are duplicating.
Basically you do the same thing, except that the start and end of i and j are different. So create a sub routine and pass them as parameter.
For example:
void get_sub_matrix(int input[][N], int start_row, int end_row, int start_col, int end_col, int[] result, int* result_offset)
{
int offset = *result_offset;
for (int i = start_row; i < end_row; i++)
{
for (int j = start_col; j < end_col; j++)
{
result[offset++] = input[i][j];
}
}
*result_offset = offset;
}
Notice how the result-offset is increased inside the routine as more elements are added to the result array.
Now you can do:
int matrix[N][N];
int array[N*N];
int k = 0;
get_sub_matrix(matrix, 0, 2, 0, 2, array, &k);
get_sub_matrix(matrix, 0, 2, 2, 4, array, &k);
get_sub_matrix(matrix, 2, 4, 0, 2, array, &k);
get_sub_matrix(matrix, 2, 4, 2, 4, array, &k);
P.S: Haven't compiled it.
For example an array: {1, 2, 3}
How do I make a program that loops this array to get an output of {1, -1, 2, -2, 3, -3}?
I tried doing something like:
#include <stdio.h>
int main()
{
int n = 3;
int arr[3] = {1, 2, 3};
int result[6];
int i, j, k;
for(i = 0; i < n*2; i++)
{
for(j = 0; j < n; j++)
{
for(k = 0; k < 2; k++)
{
if((i+1) % 2 != 0)
{
result[i] = arr[j];
}
else if((i+1) % 2 == 0)
{
result[i] = -arr[j];
}
}
}
}
for(i = 0; i < n*2; i++)
{
printf("%d ", result[i]);
}
}
But it only outputs {3, -3, 3, -3, 3, -3}
I thought my logic was perfect xD . Can anyone help?
Simple implementation: just store positive and negative values.
#include <stdio.h>
int main(void)
{
int n = 3;
int arr[3] = {1, 2, 3};
int result[6];
int i;
for (i = 0; i < n; i++)
{
result[i * 2] = arr[i];
result[i * 2 + 1] = -arr[i];
}
for(i = 0; i < n * 2; i++)
{
printf("%d\n", result[i]);
}
return 0;
}
This block seems to work:
int src[] = { 1, 2, 3};
int dest[(sizeof(src) / sizeof(int)) * 2];
int destCount = 0;
for (int i = 0; i < sizeof(src) / sizeof(int); i++) {
dest[destCount++] = abs(src[i]);
dest[destCount++] = -(abs(src[i]));
}
for (int i = 0; i < (sizeof(src) / sizeof(int)) * 2; i++) {
printf("%d\n", dest[i]);
}
I put in abs() calls to make sure you get a positive number followed by a negative number. If this isn't what you want, then just get rid of them.
Or if you just want output you could do this:
#include <stdio.h>
int main(void)
{
int n = 3;
int arr[3] = {1, 2, 3};
int i;
for (i = 0; i < n; i++)
{
printf("%d ",arr[i]);
printf("%d ",-1*arr[i]);
}
return 0;
}