【问题标题】:Swapping 2 variables from a matrix in C从C中的矩阵交换2个变量
【发布时间】:2017-04-19 03:18:44
【问题描述】:

所以我必须编写一个程序,可以从矩阵的对角线确定最大值。比我必须将矩阵的第一个变量 (a[1][1]) 的位置与该矩阵的最大值交换,其他元素保持不变。

这是我的代码:

#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;
}

我做错了什么?我的程序只用第一个变量 a[1][1] 交换最大值,但忘记将 a[1][1] 放在最大值所在的位置。

【问题讨论】:

  • 交换背后的逻辑似乎没有错 - 因此标题甚至不相关。
  • 在 C 中,数组索引从 0 开始!
  • @ZachP 好吧,逻辑很好,但它没有做我需要它做的事情。我的程序只用第一个变量 a[1][1] 交换最大值,但忘记将 a[1][1] 放在最大值所在的位置。为什么?
  • @NeacsuMihai Take a look here,也许有帮助。
  • 为什么要使用异或交换?阅读起来更加令人困惑,并且可能不会使用现代编译器为您带来任何显着的性能提升。 (见Why don't people use xor swaps?。)

标签: c


【解决方案1】:

您完全遍历对角线元素,只跟踪最大 ,然后(在循环之后)尝试将该值与矩阵的第一个元素交换。问题是您不再知道最大值在哪里,因为您从未记录过它!您只需记录 what 的值(在 max 中),并忽略它在矩阵中的 index

例如,假设您的最大值恰好是a[2][2]。您遍历对角线元素,找到最大值,将其存储在max 中。在循环结束时,您不能将a[2][2]a[0][0] 交换,因为您丢失了最大值位于a[2][2] 的信息。 (假设您从 0 开始了解有关数组索引的问题。)您正在做的是将 max 写入第一个元素 a[0][0]a[2][2] 没有改变,因为你没有改变它,而且你忘记了它在哪里改变。

您需要跟踪某个变量中的最大 max 现在写的很好)并添加另一个变量(例如,max_pos)来跟踪该最大值所在的索引。 (你只需要一个int,因为它们是对角元素,所以两个数组索引总是相同的。)任何时候你改变最大值max,也更新最大位置max_pos。这样你就知道最后要交换a[0][0]a[max_pos][max_pos]


代码可能是什么样子的简要草图(我会让你填写任何细节):

添加一个新变量的声明以跟踪最大值的位置(例如,max_pos):

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

您需要使用第一个对角元素初始化 maxmax_pos,然后遍历其他元素。

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
    }
}

请注意我如何将索引范围从 1...n1 更改为 0..n1-1。 (使这与您的其余代码保持一致。)C 中的数组索引从 0 开始,而不是从 1 开始。请注意,您不需要 do {} while () 循环。想想它到底在做什么(提示:什么都没有)。

然后,在此之后,您可以交换 a[0][0]a[max_pos][max_pos]。顺便说一句,XOR swap 不是必需的,它会使代码更难阅读。只需将值与临时变量交换即可。现代编译器非常擅长优化,并且很可能使用寄存器来实现这一点,因此您可能不会获得您认为的任何效率(而且您只做了一次)。不要试图超越你的编译器。

【讨论】:

    【解决方案2】:

    清理建议

    当你有

    int a[20][20];
    

    元素的有效范围是a[0][0] - a[19][19]

    自您使用以来,您正在所有 for 循环中访问元素 a[1][1] - a[n1][n2]

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

    除非n1 的值或n2 的值是20,否则这不是问题。

    更改要使用的循环:

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

    主要问题

    您的代码中的主要问题是您在初始化之前使用了max。在循环之前添加一行将max初始化为a[0][0]以计算其最终值。

    // 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];
        }
    }
    

    【讨论】:

    • 我做了你告诉我的事情,但是我遇到了同样的问题最大进入一个[0][0]的地方,但是一个[0][0]不去的地方最大值是..
    • @NeacsuMihai,你没有任何代码可以做到这一点。您只是交换maxa[0][0] 的值。您没有交换任何其他值。
    • 伙计...我知道我没有交换除 max 和 a[0][0] 之外的任何其他值;如果我运行这个程序,我会得到一个只有 a[0][0] 改变的矩阵......我不知道如何更清楚地解释它,尝试运行它......例如,我的最大值是[2][2] 是,所以它应该将 a[2][2] 的值与 a[0][0] 交换,好吧.. 这是错误的,因为我的程序只放置了 a[2][ 的值2] over a[0][0],所以它不会交换它们..现在你明白我的问题是什么了....?
    猜你喜欢
    • 2019-03-24
    • 2011-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-07
    • 2012-11-08
    • 1970-01-01
    相关资源
    最近更新 更多