计算矩阵对角线之和

10

我需要在C++中计算矩阵的两条对角线之和,尽管我已经有了一个解决方案,但我很蠢因为我无法理解它在做什么,所以我想知道是否有另一个版本的解决方案,我可以理解。以下是执行此任务的代码:

cout<<"Jepi rangun e  matrices"<<endl;  // pra bejme manipulim me matrice katrore ku rreshtat=kolonat
cin>>n;
cout<<"Tani jepi elementet e matrices"<<endl; // lexohet matrica

for(i=1;i<=n;i++)
{
     for(j=1;j<=n;j++)
        cin>>a[i][j];
}

d=0;
s=0; // ketu e keni kushtin si dhe mbledhjen per te dy diagonalet me dy variabla te ndryshme

for(i=1;i<=n;i++)
    for(j=1;j<=n;j++)
    {
        if(i==j)
            d=d+a[i][j];
        if(j==n-i+1 || i==n-j+1) 
            s=s+a[i][j];
    }

难以理解的部分是:

if(j==n-i+1 || i==n-j+1) 
    s=s+a[i][j];

这是我改变了整个代码,但它不能处理次对角线:

#include <iostream>
using namespace std;

int main()
{
    int d=0,s=0; // ketu e keni kushtin si dhe mbledhjen per te dy diagonalet me dy variabla te ndryshme
    int i,j,n;
    int a[5][5];

    cout<<"Jepi rangun e  matrices"<<endl;  // pra bejme manipulim me matrice katrore ku rreshtat=kolonat
    cin>>n;
    cout<<"Tani jepi elementet e matrices"<<endl; // lexohet matrica

    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
            cin>>a[i][j];
    }

    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
            if(i==j) 
                d+=a[i][j]; //principal diagonal 
            if(i+j==n-1)
                s+=a[i][j];//secondary diagonal

        }
    }

    cout << d << endl;
    cout << s << endl;
    cin.get();
    cin.get();
    return 0;
}

您对此代码的任何部分有具体问题吗? - Drew Dormann
@DrewDormann 是的,这就是问题所在: 如果(j==n-i+1 || i==n-j+1),则s=s+a[i][j]; - Igor Ivanovski
5个回答

22

希望评论可以用英语,但是你的代码(第二个循环)做了什么:

browse all rows
  browse all cells
    if i == j (is in main diagonal):
        increase one sum
    if i == n - i + 1 (the other diagonal)
        increase the second sum

使用n而不是n^2的代码更加简洁且更有效:

for( int i = 0; i < n; i++){
   d += a[i][i];  // main diagonal
   s += a[i][n-i-1]; // second diagonal (you'll maybe need to update index)
}

这个方法直接穿过了矩阵的两条对角线(在同一个循环中),而且不会穿过其他项。

编辑:

主对角线具有坐标{(1,1),(2,2),...,(i,i)}(因此i == j)。

副对角线在3x3矩阵中的坐标是:{(1,3),(2,2),(3,1)},一般地,它的坐标为:{(1,n-1+1),(2,n-2+1),...(i,n-i+1),....,(n,1)}。但在C中,数组的索引从0开始,不是1,所以你不需要那个+1(可能不需要)。

所有满足条件i == n - j + 1 的副对角线上的元素(再次由于C的索引从0开始,+1变成了-1(例如当i=0n=3j=2时,j=n-i-1)。

你可以在一个循环中实现所有这些(参见上面的代码)。


@cyborg n=5; i=0; 这意味着第二个索引 j=6; 超出了边界(在这种情况下,我假设 j=4 才是正确的)。 - Vyktor

6
int diag1=0;
int diag2=0;

for (i=0;i<n;i++)
 for (j=0;j<n;j++){

  if(i==j)  diag1+=a[i][j]; //principal diagonal 
  if(i+j==n-1) diag2+=a[i][j];//secondary diagonal

为了更好地理解这个算法,您应该在笔记本上绘制一个矩阵,并用它们在矩阵中的位置编号,然后逐步应用算法。我100%确定您会理解。


1
是的,我画了矩阵但还是迷失了...但是现在我看到你的代码后就明白了,这很有帮助:如果(i+j=n-1)。 - Igor Ivanovski
尝试模仿计算机的行为。使用n=3和以下数值: a(1,1) a(1,2) a(1,3), a(2,1) a(2,2) a(2,3), a(3,1) a(3,2) a(3,3) (将a替换为数字) 然后进入循环,记录你的i和j,然后检查if语句。 - Ionel Lupu
我在C++中尝试了这个,但对于次对角线它没有起作用。 - Igor Ivanovski
我的算法使用这个for循环(i=0;i<n;i++)。但是对于你的for循环,它用于次对角线,如果(i+j==n+1)。 - Ionel Lupu

4

我来尝试解释一下这个版本,好吗? :D

代码有三个重要部分:

  • 输入矩阵
  • 计算主对角线(\ 方向)
  • 计算次对角线(/ 方向)

接下来将逐一解释:

// input elements
for(i=1;i<=n;i++) // from left to right
{
    for(j=1;j<=n;j++) // from up to down
        cin>>a[i][j]; // input element at (i,j) position
}

在这里,d和s分别包含主对角线和副对角线的交错值。在2个循环结束时,它们将包含结果。
for (i=1;i<=n;i++)
     for (j=1;j<=n;j++)
     {
        if(i==j)          // major diagonal - if coordinates are the same
           d=d+a[i][j];   // e.g. (1,1), (2,2)
        if(j==n-i+1 || i==n-j+1)  // coordinates of the minor diagonal - check
           s=s+a[i][j];           // e.g. n=3 (3,1) (2,2) ...
      }

希望这可以帮助到您。

请注意此代码以矩阵坐标为1开始而不是0,因此您实际上需要为矩阵分配(n+1)x(n+1)的空间:

double a[n+1][n+1];

在使用之前。

另外,您提供的代码并不是最有效的。它具有O(n^2)的复杂度,而任务可以像这样在O(n)内完成:

// matrix coordinates now start from 0
for (int i=0; i < n; ++i){
    d += a[i][i]; // major
    s += a[i][n-1-i]; // minor
}

0

对于次对角线,您必须使用i + j == n + 1而不是i + j == n - 1

for(i = 1; i <= n; i++)
{
    for(j = 1; j <= n; j++)
    {
        if(i == j) 
            d += a[i][j]; //principal diagonal 
        if(i + j == n+1)
            s += a[i][j];//secondary diagonal

    }
}

0
int num[5][5]={0}; //decleration
int i=0,j=0,sum=0; 
for (int i=0;i<5;i++)
{
    for (int j=0;j<5;j++)
    {
        cin>>num[i][j];
    }                          //Taking Matrix input
}
        cout<<endl<<"The Matrix is "<<endl;
    for (int i=0;i<5;i++)
    {
        for (int j=0;j<5;j++)
        {
            cout<<num[i][j]<<" ";
        }
            cout<<endl;               //Displaying the Matrix
    }                               
cout<<endl<<"The sum of diagonals of the matrix is "<<endl;
if(i==j) 
{
    for (i=0;i<5;i++)
    {
        for (j=0;j<5;j++)
        {
            if (i==j)       //This loop works where i and j will be equal
            {
            sum=sum+num[i][j];
            }
        }
    }
    cout<<sum;
}
else   //Some times the user creates 4 x 3 matrix or so than diagonals not match so. . . 
{
    cout<<"The sum is not Possible";
}

我认为这是这个矩阵最简单的解决方案。. . .!! - Abdul Rehman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接