Calculating and printing the sums of the diagonals of a matrix - c

This is a program that is supposed to calculate the sum of all the diagonals in the matrix and then print them out.
ex. if the matrix is
1 2 3 4 5
2 3 4 5 6
0 1 1 2 5
5 5 5 5 5
7 8 9 7 7
the output should be
17 13 13 10 5
15 17 13 13 10
14 15 17 13 13
13 14 15 17 13
7 13 14 15 17
#include <stdio.h>
int main()
{
int n, sum=0, i, j, sub_i, sub_j, sub1_i, sub1_j;
scanf("%d ", &n);
int array1[n][n];
for(i=0;i<n;i++){
for(j=0; j<n; j++){
scanf("%d", &array1[i][j]);
}
}
for(i=0; i<n; i++){
for(j=0; j<n; j++){
sub_i=i;
sub_j=j;
sub1_i=i;
sub1_j=j;
sum=0;
if(j>i){
while(sub_j<n){
sum+=array1[sub_i][sub_j];
sub_i++;
sub_j++;
}
while(sub_j<n){
array1[sub_i][sub_j]=sum;
sub1_i++;
sub1_j++;
}
}
if(i>j){
while(sub_i<n){
sum+=array1[sub1_i][sub1_j];
sub_i++;
sub_j++;
}
while(sub1_i<n){
array1[sub1_i][sub1_j]=sum;
sub1_i++;
sub1_j++;
}
}
}
}
for(i=0; i<n; i++){
for(j=0; j<n; j++){
printf("%d ", array1[i][j]);
}
printf("\n");
}
return 0;
}
When i run the program it prints the array as if no value was assigned to the matrix. Can someone point out what is happening?

Quoting the comment by Weather Vane:
The program alters the array it is examining — see array1[sub_i][sub_j]=sum; — and then prints incorrect values, since you can't correctly sum the diagonals of an array that is changing.
The OP already realize that
... what you are telling me is to assign the values to another array and print that.
Yes, that is way easier:
#include <stdio.h>
int main(void)
{
int n;
// Checking the input is always a good idea, but you
// may prefer something less brutal, in case of error
if (scanf("%d", &n) != 1 || n < 1)
return 1;
int mat[n][n];
for (int i = 0; i < n; ++i) {
for (int j= 0; j < n; ++j) {
if (scanf("%d", &mat[i][j]) != 1)
return 1;
}
}
// Calculate and store the sum of the diagonals. Note that
// it could be done in the previous loop, but it may be better
// to refactor those snippets into separate functions.
int diagonals[2 * n + 1];
for (int i = 0; i < 2 * n + 1; ++i)
diagonals[i] = 0; // consider 'memset' instead of this loop
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
diagonals[n + i - j] += mat[i][j];
}
}
// Now print the correct values in their position
for(int i = 0; i < n; ++i) {
for(int j = 0; j < n; ++j) {
printf("%4d", diagonals[n + i - j]);
}
printf("\n");
}
return 0;
}
Testable HERE.

You can do like the follow:
#include <stdio.h>
#define N 5
int main()
{
int array[N][N] = {
1, 2, 3, 4, 5,
2, 3, 4, 5, 6,
0, 1, 1, 2, 5,
5, 5, 5, 5, 5,
7, 8, 9, 7, 7};
for(int i = 1; i < N; ++i)
for(int j = 1; j < N; ++j)
array[i][j] += array[i - 1][j - 1];
for (int i = 0; i + 1 < N; ++i)
for (int j = 0; j + 1 < N; ++j)
if (i == j)
array[i][j] = array[N - 1][N - 1];
else if (i > j)
array[i][j] = array[N - 1][N - 1 - i + j];
else
array[i][j] = array[N - 1 - j + i][N - 1];
for (int i = 0; i < N; ++i) {
for(int j = 0; j < N; ++j)
printf("%d ", array[i][j]);
printf("\n");
}
return 0;
}

Related

Printing format with printf

I'm doing the past exam and everything has been going well, I've finished the task, but I have some formatting problems.
What I get:
What I want to achieve:
It bothers me and I would be grateful if someone could come up with a solution.
My code for printing the array:
void printArray(int tab[][MAX], int n, int m) {
for (int j = 0; j < m; j++)
{
printf("%5d", j);
}
printf("\n");
for (int k = 0; k < 3 * n + 4; k++)
{
printf("-");
}
printf("\n");
for (int i = 0; i < n; i++)
{
printf("%2d |", i);
for (int j = 0; j < m; j++)
{
printf("%3d", tab[i][j]);
}
printf("\n");
}
}
The offset is off and printf("%5d", j); makes the heading numbers too wide.
Fix it by prepending the first line, but instead of printf("%2d |", i); that you use to prepend each line when printing the values, you can use a blank string, printf("%2s |", "");.
void printArray(int tab[][MAX], int n, int m) {
printf("%2s |", ""); // this fixes the offset
for (int j = 0; j < m; j++)
{
printf("%3d", j); // and use the same width as when printing the values
}
// ...
Here's my solution, with liberal use of width specifiers on the printf statements.
As you change the constant COL_WIDTH, the table should generally automatically adjust.
#include <stdio.h>
void printArray(int tab[][4], int n, int m)
{
const int COL_WIDTH = 4;
printf("%*.*s|", COL_WIDTH, COL_WIDTH, "");
for (int j = 0; j < m; j++)
{
printf("%*d", COL_WIDTH, j);
}
printf("\n%.*s", COL_WIDTH*(n+1)+1, "----------------------------------------");
for (int i = 0; i < n; i++)
{
printf("\n%*d |", COL_WIDTH-1, i);
for (int j = 0; j < m; j++)
{
printf("%*d", COL_WIDTH, tab[i][j]);
}
}
}
int main(void) {
int table[][4] = { { 1, 2, 1, 2}, {2, 2, 3, 2}, {1, 3, 2, 3}, {2, 2, 2, 1} };
printArray(table, 4, 4);
return 0;
}
Output
| 0 1 2 3
---------------------
0 | 1 2 1 2
1 | 2 2 3 2
2 | 1 3 2 3
3 | 2 2 2 1

Why is the multiplication doubling in this C loop?

The code is supposed to take inputs to form a 3x3 Matrix and then multiply each term by the diagonal element of that line, but, for some reason that i don't know, it multiplies two times by the diagonal when the column index is bigger than the row index.
#include <stdio.h>
#define R 3
int a[R][R], i, j;
int main(void) {
for (i = 0; i < R; i++) {
for (j = 0; j < R; j++) {
printf("\nInsira o n%i%i ", i, j);
scanf("%i", &a[i][j]);
}
}
for (i = 0; i < R; i++) {
for (j = 0; j < R; j++) {
a[i][j] = a[i][j] * a[i][i];
}
}
for (i = 0; i < R; i++) {
printf("\n");
for (j = 0; j < R; j++) {
printf("%i ", a[i][j]);
}
}
}
input:
9 8 7
6 5 4
3 2 1
output:
81 648 567
30 25 100
3 2 1
The diagonal value for a given row is being changed before that row has been fully multiplied, so once the column goes past the diagonal, the multiplies are using the new value of that diagonal rather than the old value.
You can fix it (and improve the speed) as follows:
for (i = 0; i < R; i++) {
int tmp = a[i][i];
for (j = 0; j < R; j++) {
a[i][j] *= tmp;
}
}
Also, as mentioned, both i and j should be local variables.

how to return the last element of each row in C

This exercise asks me to fill the first row of the matrix then put the last element of each row in the first box of the next row and transfers the elements of the previous row to the next row like the following example:
5 7 9 2
2 5 7 9
9 2 5 7
7 9 2 5
5 7 9 2
The problem is start from the second row to the end in my code(the program does not return the last value of row 1 to the row 2) , can you help me
my code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int rows=5,cols=4;
int T[rows][cols];
int p=1;
printf("The filling of this matrix :\n");
for(int i=0;i<rows;i++)
{
for(int j=0;j<cols;j++)
{
if(i==0)
{
scanf("%d",&T[i][j]);
}
T[p][0]=T[p-1][cols-1];
for(int k=1;k<rows;k++)
{
T[k][j+1]=T[k-1][j];
}
}
p++;
}
printf("\nThe display of this matrix :\n");
for(int i=0;i<rows;i++)
{printf("\n");
for(int j=0;j<cols;j++)
{
printf("[%d]",T[i][j]);
}
}
}
#include <stdio.h>
int main(void){
int rows = 5, cols = 4;
int T[rows][cols];
printf("Filling the first row\n");
for(int i=0; i < cols; i++){
printf("Enter T[0][%d] = ",i)
scanf("%d",&T[0][i]);
}
printf("Filling the rest matrix\n");
for(i=1; i < rows; i++){
for(j=0; j < cols; j++){
if(j == 0){
T[i][j] = T[i-1][cols-1];
}
else{
T[i][j] = T[i-1][j-1];
}
}
}
printf("display the matrix\n");
for(i=0 ; i < rows; i++){
for(j=0 ; j < cols; j++){
printf(" %d ",T[i][j]);
}
printf("\n")
}
}
You are accessing outside of the bounds of the array here:
T[k][j+1]=T[k-1][j]; // j + 1 = 4 in the last iteration in a range [0 ... 3]
You are over-complicating things, you don't need an extra loop (k) nor an extra variable (p), all the information needed is already in the inner loop, just check the position of i and j:
#include <stdio.h>
int main(void)
{
int rows = 5, cols = 4;
int T[rows][cols]; // Notice that this is a VLA, avoid using
// them and use enum {rows = 5, cols = 4}
// when values are known before hand
printf("The filling of this matrix :\n");
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
if (i == 0)
{
scanf("%d", &T[i][j]);
}
else
{
if (j == 0)
{
T[i][j] = T[i - 1][cols -1];
}
else
{
T[i][j] = T[i - 1][j - 1];
}
}
}
}
printf("\nThe display of this matrix :\n");
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
printf("[%d]", T[i][j]);
}
printf("\n");
}
}
You can simplify:
if (j == 0)
{
T[i][j] = T[i - 1][cols -1];
}
else
{
T[i][j] = T[i - 1][j - 1];
}
using a ternary operator:
T[i][j] = T[i - 1][(j == 0) ? cols - 1 : j - 1];

Getting wrong output when adding elements in 2D Array

I am studying C programming now, I am not getting correct output when I am adding two elements in array, i am expecting your help to know the issue.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int limit = 0, sum[limit][3];
int a[limit][3];
int b[limit][3];
printf("Enter the size of arrays: \n");
fflush(stdout);
scanf("%d", &limit);
printf("Enter the values of Array 1");
fflush(stdout);
for (int i = 0; i < limit; i++) {
for (int j = 0; j < limit; j++) {
scanf("%d", &a[i][j]);
}
}
printf("Array 1: \n");
fflush(stdout);
for (int i = 0; i < limit; i++) {
for (int j = 0; j < limit; j++) {
printf("%d\t", a[i][j]);
}
printf("\n");
}
printf("Enter the values of Array 2");
fflush(stdout);
for (int i = 0; i < limit; i++) {
for (int j = 0; j < limit; j++) {
scanf("%d", &b[i][j]);
}
}
printf("Array 2: \n");
for (int i = 0; i < limit; i++) {
for (int j = 0; j < limit; j++) {
printf("%d\t", b[i][j]);
}
printf("\n");
}
for (int i = 0; i < limit; i++) {
for (int j = 0; j < limit; j++) {
sum[i][j]= a[i][j] + b[i][j];
}
}
printf("Sum of 2 arrays: \n");
for (int i = 0; i < limit; i++) {
for (int j = 0; j < limit; j++) {
printf("%d\t", sum[i][j]);
}
printf("\n");
}
return EXIT_SUCCESS;
}
Current output:
Enter the size of arrays:
3
Enter the values of Array 1
12
12
12
12
12
12
12
12
12
Array 1:
12 12 12
12 12 12
12 12 12
Enter the values of Array 2
11
11
11
11
11
11
11
11
11
Array 2:
11 11 11
11 11 11
11 11 11
Sum of 2 arrays:
22 22 22
22 22 22
22 22 22
The problem i found that the exact array i gave in code that doesn't workout.
My expected output is:
23 23 23
23 23 23
23 23 23
In:
int limit = 0, sum[limit][3];
int a[limit][3];
int b[limit][3];
limit is 0, your arrays will be:
int sum [0][3];
int a[0][3];
int b[0][3];
They will have space for nothing.
You should declare your arrays only after the limit input.
Also note that the second dimension of the array is fixed at 3, in your inner for cycles, instead of using limit you should use that constant value, otherwise, if limit is 4 or more, your program will access the array outside its bounds, invoking undefined behavior.
There are multiple problems:
the arrays are defined with a dimension set to 0:
int limit = 0, sum[limit][3];
int a[limit][3];
int b[limit][3];
you should define the arrays after you read the value og limit.
the nested loops use an incorrect boundary test:
for (int i = 0; i < limit; i++) {
for (int j = 0; j < limit; j++) {
j should iterate from 0 to 3 excluded.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int limit = 0;
printf("Enter the size of arrays: \n");
fflush(stdout);
if (scanf("%d", &limit) != 1 || limit < 1)
return 1;
int sum[limit][3];
int a[limit][3];
int b[limit][3];
printf("Enter the values of Array 1");
fflush(stdout);
for (int i = 0; i < limit; i++) {
for (int j = 0; j < 3; j++) {
scanf("%d", &a[i][j]);
}
}
printf("Array 1: \n");
fflush(stdout);
for (int i = 0; i < limit; i++) {
for (int j = 0; j < 3; j++) {
printf("%d\t", a[i][j]);
}
printf("\n");
}
printf("Enter the values of Array 2");
fflush(stdout);
for (int i = 0; i < limit; i++) {
for (int j = 0; j < 3; j++) {
scanf("%d", &b[i][j]);
}
}
printf("Array 2: \n");
for (int i = 0; i < limit; i++) {
for (int j = 0; j < 3; j++) {
printf("%d\t", b[i][j]);
}
printf("\n");
}
for (int i = 0; i < limit; i++) {
for (int j = 0; j < 3; j++) {
sum[i][j] = a[i][j] + b[i][j];
}
}
printf("Sum of 2 arrays: \n");
for (int i = 0; i < limit; i++) {
for (int j = 0; j < 3; j++) {
printf("%d\t", sum[i][j]);
}
printf("\n");
}
return EXIT_SUCCESS;
}
In the inner nested loops,j should iterate till j(excluding it) not limit.
Required nested loop should be like-
for (int i = 0; i < limit; i++) {
for (int j = 0; j < 3; j++) {
.
.
}
Tip:Declare your array after getting the input/size of the array from the user.

Change column into row after a given number N

I need to change the matrix columns into rows after a given number N. For example if N = 3 then the row is n * 2 given in this exercise. Now after the 3rd column every other column needs to be a row. I know how to transpose a matrix but I get confused how to do it after given N.
Code:
#include <stdio.h>
int main() {
int n;
int a[n][n * 2];
int b[n * 2][n];
scanf("%d", &n);
for(int i = 0;i < n; i++) {
for(int j = 0; j < n * 2; j++) {
scanf("%d", a[i][j]);
}
}
for(int i = 0; i < n * 2; i++) {
for(int j = 0; j < n; j++) {
a[i][j] = b[j][i];
}
}
return 0;
}
Example for n = 3.
1 2 3 4 5 6
7 8 9 10 11 12
13 14 15 16 17 18
I need to achieve
1 2 3
7 8 9
13 14 15
4 5 6
10 11 12
16 17 18
First square of the matrix (array) is left unchanged, so both arrays have the same starting. Later part is shifted n units left and n units down, so the following code should help you to solve the problem:
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
b[i][j] = a[i][j];
}
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
b[i + n][j] = a[i][j + n];
}
}
As both set of for loops have the same kind of variable changes, we can converge them into one, as #Chris Turner did.
The whole code should look something like this:
#include <stdio.h>
int main() {
int n;
scanf("%d", &n);
int a[n][n * 2];
int b[n * 2][n];
for(int i = 0;i < n; i++) {
for(int j = 0; j < n * 2; j++) {
scanf("%d", &a[i][j]);
}
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
b[i][j] = a[i][j];
b[i + n][j] = a[i][j + n];
}
}
return 0;
}
Firstly you need to initialise n before you use it. In the code below, n has no defined value, so using it to define the size of your arrays leads to undefined behaviour.
int n;
int a[n][n * 2];
int b[n * 2][n];
You can move the array definitions until after you've set n
Secondly, when using scanf to read in an int you have to pass in a pointer to the variable, so this line is wrong and your compiler should be throwing up warnings about it
scanf("%d", a[i][j]);
it should be
scanf("%d", &a[i][j]);
if you want to copy from a into b you need to do it the right way around
you've got which is copying from b to a and also goes out of bounds as i goes up to n*2 and a's first index is just n.
a[i][j] = b[j][i]
what you want is just this.
b[i][j] = a[j][i]
But that doesn't solve your problem as that is just transposing and you're trying to split the matrix in half and stack it differently. So to start with you need to copy the first n by n elements from a to b like this.
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
b[i][j] = a[i][j];
and then to copy the second chunk you can use the same loops and offset by n
b[i+n][j] = a[i][j+n];
After all these changes your code should look like this:
#include <stdio.h>
int main() {
int n;
scanf("%d", &n);
int a[n][n * 2];
int b[n * 2][n];
for(int i = 0;i < n; i++) {
for(int j = 0; j < n * 2; j++) {
scanf("%d", &a[i][j]);
}
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
b[i][j] = a[i][j];
b[i+n][j] = a[i][j+n];
}
}
return 0;
}

Resources