0

So I have to make a program that can determinate the maximum from the diagonal of a matrix. Than I have to swap it's place of the first variable of the matrix (a[1][1]) with the maximum of that matrix, the other elements beeing unchanged.

Here is my code:

#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>

int a[20][20];
int main(){
    int i, j, n1, n2, max;
    printf ("\nIntroduceti numarul de coloane pentru matricea A: ");
    scanf (" %d", &n2);
    printf ("\nIntroduceti numarul de randuri pentru matricea A: ");
    scanf (" %d", &n1);
    printf("\nIntroduceti elementele primei matrice: ");
    for(i=1;i<=n1;i++){
        for(j=1;j<=n2;j++){
            printf("\na[%d][%d] = ", i, j);
            scanf("%d",&a[i][j]);
        }
    }
    printf("\nMatricea A este:\n");
    for(i=1;i<=n1;i++){
        printf("\n");
        for(j=1;j<=n2;j++){
            printf("%d\t",a[i][j]);
        }
    }


    do {
        for(i=1;i<=n1;i++){
            if(a[i][i]>max) {
                max=a[i][i];
            }
        }
    } while (i<=n1);
    printf ("\nMaximul de pe diagonala este: %d", max);

    a[1][1]=a[1][1]^max;
    max=max^a[1][1];
    a[1][1]=max^a[1][1];

        for(i=1;i<=n1;i++){
        printf("\n");
        for(j=1;j<=n2;j++){
            printf("%d\t",a[i][j]);
        }
    }

    return 0;
}

What I did wrong? My program swaps only the maximum with the first variable a[1][1], but forgets to place a[1][1] where the maximum is.

Neacsu Mihai
  • 127
  • 5
  • 2
    The logic behind your swapping doesn't seem wrong - therefore the title isn't even relevant. – Zach P Dec 04 '16 at 18:49
  • 6
    In C, array indices start with 0! – Am_I_Helpful Dec 04 '16 at 18:49
  • @ZachP Well, the logic is good, but it doesn't do what i need it to do. My program swaps only the maximum with the first variable a[1][1], but forgets to place a[1][1] where the maximum is. Why? – Neacsu Mihai Dec 04 '16 at 18:53
  • @NeacsuMihai [Take a look here](http://ideone.com/CrKFJc), maybe helps. – Michi Dec 04 '16 at 18:57
  • Why are you using XOR swap? It's more confusing to read and probably won't give you any significant performance gain with a modern compiler. (See [Why don't people use xor swaps?](http://stackoverflow.com/questions/16535461/why-dont-people-use-xor-swaps).) – e0k Dec 04 '16 at 19:01
  • Add a variable to save the i when you save the max, then `a[max_i][max_i] = a[1][1]; a[1][1] = max;` – cpatricio Dec 04 '16 at 19:02
  • @e0k I've tried using a 3rd variable too, but I got the same problem, that i get using XOR swap too.. – Neacsu Mihai Dec 04 '16 at 19:03
  • @NeacsuMihai Youd do not really need [a 3rd variable](http://ideone.com/t1UgtP). – Michi Dec 04 '16 at 19:09
  • Wouldn't you need to keep track of both the maximum _value_ and the _index_ where the maximum value is located? Otherwise, how could you swap elements in the matrix without knowing _where_ the maximum is (in addition to _what_ it is)? – e0k Dec 04 '16 at 19:50
  • @e0k Yes, I have to track both of those things, but I don't know how to programm it.. – Neacsu Mihai Dec 04 '16 at 19:59

2 Answers2

3

You iterate completely through the diagonal elements, keeping track of only the maximum value, then (after the loop) you try to swap this value with the first element of the matrix. The problem is that you no longer know where the maximum value was, since you never recorded that! You just record what the value was (in max), and ignored its index in the matrix.

For example, suppose your maximum value happens to be at a[2][2]. You iterate through the diagonal elements, find the maximum value, store it in max. At the end of your loop, you can't swap a[2][2] with a[0][0] because you lost the information that the maximum is at a[2][2]. (Assuming you learned the issue about array indexes starting at 0.) What you are doing is writing max to the first element a[0][0]. a[2][2] is unchanged because you don't change it, and you forgot where it was to change it anyway.

You need to keep track of the maximum value in some variable (max as it is written now is fine) and add another variable (say, max_pos for example) to keep track of the index of where this maximum value is. (You only need one int because they're diagonal elements, so both array indexes are always the same.) Any time you change the maximum value max, also update the maximum position max_pos. This way you would know at the end to swap a[0][0] and a[max_pos][max_pos].


A brief sketch of what the code might look like (I'll leave it you to fill in any details):

Add a declaration of a new variable to keep track of the position (say, max_pos) of the maximum value:

int i, j, n1, n2, max, max_pos;

You need to initialize max and max_pos with the first diagonal element, then iterate through the others.

max = a[0][0];
max_pos = 0;
for (i=0; i<n1; i++){
    if (a[i][i] > max) {
        max = a[i][i];
        max_pos = i;    // update max_pos anytime max is updated
    }
}

Notice how I changed the range of the indexes from 1...n1 to 0..n1-1. (Make this consistent with the rest of your code.) Array indexes in C start with 0, not with 1. Notice here that you don't need that do {} while () loop. Think about what it is really doing (hint: nothing).

Then, after this, you can swap a[0][0] and a[max_pos][max_pos]. By the way, XOR swap is not necessary and makes the code harder to read. Just swap values with a temporary variable. Modern compilers are very good at optimizing and can likely implement this with registers, so you're probably not gaining whatever efficiency you think you are (and you're only doing it once). Don't try to outsmart your compiler.

Community
  • 1
  • 1
e0k
  • 6,961
  • 2
  • 23
  • 30
1

Suggestion for cleanup

When you have

int a[20][20];

The valid range of elements are a[0][0] - a[19][19].

You are accessing elements a[1][1] - a[n1][n2] in all the for loops since you are using:

for(i=1;i<=n1;i++){
    for(j=1;j<=n2;j++){

That won't be a problem unless the value of n1 or the value of n2 is 20.

Change those loops to use:

for(i=0; i < n1; i++){
    for(j=0; j < n2; j++){

Main problem

The main problem in your code is that you are using max before it's initialized. Add a line to initialize max to a[0][0] before the loop to compute its final value.

// Remove the `do-while` part. You don't need it.
max = a[0][0];
for(i=0; i < n1; i++){
    if(a[i][i]>max) {
        max=a[i][i];
    }
}
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • I did the things you told me, but I encounter the same problem maximum goes into a[0][0] place, but a[0][0] don't go in the place where maximum is.. – Neacsu Mihai Dec 04 '16 at 19:17
  • @NeacsuMihai, you don't have any code for doing that. You are only swapping the values of `max` and `a[0][0]`. You are not swapping any other values. – R Sahu Dec 04 '16 at 19:26
  • Man... I get it that I am not swapping any other values than max and a[0][0]; If I run this program I will get a matrix where only a[0][0] is changed... I don't know how to explain it more clearly, try to run it... Example, my maximum is where a[2][2] is, so it should swap the value of a[2][2] with a[0][0], well.. This is false because my program only puts the value of a[2][2] over a[0][0], so it does not swap them.. Now you understand what is my problem....? – Neacsu Mihai Dec 04 '16 at 19:31