二维数组中的意外输出

时间:2019-09-24 11:40:07

标签: c loops for-loop multidimensional-array

给出一个6x6 2D阵列,:

1 1 1 0 0 0
0 1 0 0 0 0
1 1 1 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0

在此图形表示形式中,我们将沙漏定义为值的子集,其中索引按此模式落入

a b c
  d
e f g

arr中有16个沙漏,沙漏和是沙漏值的总和。计算以arr为单位的每个沙漏的沙漏总和,然后打印最大沙漏总和。

例如,给定2D数组:

-9 -9 -9  1 1 1 
 0 -9  0  4 3 2
-9 -9 -9  1 2 3
 0  0  8  6 6 0
 0  0  0 -2 0 0
 0  0  1  2 4 0

我们计算以下16个沙漏值:

-63, -34, -9, 12, 
-10, 0, 28, 23, 
-27, -11, -2, 10, 
 9, 17, 25, 18

这是我编写的代码

#include<stdio.h>

const int M=6;
const int N=6;

int hourglassSum(int arr_rows, int arr_columns, int arr[M][N]) {
    int rows,columns;
    rows=arr_rows-(arr_rows/3);
    columns=arr_columns-(arr_columns/3);
    int a[columns-1][rows-1];
    int min_r,min_c,max_r,max_c,sum;
    sum=0;
    for(int k=0;k<columns;k++)
    {
        min_c=k;
        max_c=k+2;
        for(int l=0;l<rows;l++)
        {
            min_r=l;
            max_r=l+2;
            sum=0;
            for(int i=min_c;i<=max_c;i++)
            {
                if(max_c>=arr_columns)
                    break;
                for(int j=min_r;j<=max_r;j++)
                {
                    if(max_r>=arr_rows)
                        break;
                    if(i!=min_c && i!=max_c)
                    {
                        int no=j+1;
                        sum +=arr[i][no];
                        break;
                    }
                    sum += arr[i][j];
                }
            }
            a[min_c][min_r]=sum;
        }
    }
    int max=-111;
    for(int b=0;b<columns;b++)
    {
        for(int c=0;c<rows;c++)
        {
            if(max<a[b][c])
                max=a[b][c];
        }
    }
    for(int i=0;i<columns;i++)
    {
        for(int j=0;j<rows;j++)
            printf("%d ",a[i][j]);
        printf("\n");
    }
    return max;

}

int main()
{
    int arr[6][6];
    int arr_rows=6;
    int arr_columns=6;
    for(int i=0;i<arr_columns;i++)
        for(int j=0;j<arr_rows;j++)
            scanf("%d",&arr[i][j]);
    int result=hourglassSum(arr_rows,arr_columns,arr);
    printf("\n%d",result);
}

我输入为

-9 -9 -9 1 1 1
 0 -9 0 4 3 2
-9 -9 -9 1 2 3
 0 0 8 6 6 0
 0 0 0 -2 0 0
 0 0 1 2 4 0

预期输出为

-63 -34 -9 12
-10 0 28 23 
-27 -11 -2 10
9 17 25 18

但我的输出是

-63 -34 -9 -10
-10 0 28 -27
-27 -11 -2 9
9 17 25 18

怎么了?

2 个答案:

答案 0 :(得分:0)

要输出最大和,不需要创建辅助数组。您所需要做的就是正确计算两个嵌套循环的迭代次数。

在您的函数中,这些计算和数组的声明

rows=arr_rows-(arr_rows/3);
columns=arr_columns-(arr_columns/3);
int a[columns-1][rows-1];

不正确。例如,不清楚为什么数组的行数等于columns - 1的值。

该函数可以更简单地编写。

您在这里。

#include <stdio.h>

enum { M = 6, N = 6 };

long long int hourglassSum( int ( *a )[N], size_t m )
{
    long long int max_sum = 0;

    const size_t SIZE = 3;

    if ( !( m < SIZE ) )
    {
        max_sum = ( long long int )
                  a[0][0] + a[0][1] + a[0][2] + 
                            a[1][1] +
                  a[2][0] + a[2][1] + a[2][2];

        for ( size_t i = 0; i + SIZE - 1 < m; i++ )
        {
            for ( size_t j = i == 0 ? 1 : 0; j + SIZE - 1 < N; j++ )
            {
                long long int sum = ( long long int )
                                    a[i][j]   +  a[i][j+1]   + a[i][j+2] +
                                                 a[i+1][j+1] +
                                    a[i+2][j] +  a[i+2][j+1] + a[i+2][j+2];

                // printf( "%lld\n", sum );                    
                if ( max_sum < sum ) max_sum = sum;                                 
            }
        }
    }

    return max_sum;
}

int main(void) 
{
    int a[M][N] =
    {
        { -9, -9, -9,  1, 1, 1 }, 
        {  0, -9,  0,  4, 3, 2 },
        { -9, -9, -9,  1, 2, 3 },
        {  0,  0,  8,  6, 6, 0 },
        {  0,  0,  0, -2, 0, 0 },
        {  0,  0,  1,  2, 4, 0 }    
    };

    long long int sum = hourglassSum( a, M );

    printf( "Hourglass Sum = %lld\n", sum );

    return 0;
}

程序输出为

Hourglass Sum = 28

答案 1 :(得分:0)

您的计算:

rows=arr_rows-(arr_rows/3);
columns=arr_columns-(arr_columns/3);

因为6 / 3为2,所以会产生正确的答案,这是要减去的正确值。如果矩阵为12x12,则将省略行和列-由于沙漏的形状,您应减去2(对于非正方形的一般情况,应减去hourglass_width - 1hourglass_height - 1沙漏)。

使用int max=-111;是危险的-再次,它碰巧适用于示例数据,但这不是一般的解决方案。使用a[0][0]中的值作为初始最大值。这可能是一个幸运的猜测,实际上是最大值,但是如果有一个最大值,它将被另一个较大的值代替。

您应消除MN并使用:

int hourglassSum(int arr_rows, int arr_columns, int arr[arr_rows][arr_columns]) {

这将允许您将其他大小的数组传递给代码。

但是,主要问题是使a矩阵太小。 您应该使用int a[columns][rows]。 (C语言中的数组通常为a[rows][columns],但是如果您保持一致,则可以将它们取反,无论如何,rows == columns的区别都无关紧要。)使用小尺寸矩阵,我得到的结果是;使用正确大小的矩阵,我得到了预期的结果。

#include <stdio.h>

static int hourglassSum(int arr_rows, int arr_columns, int arr[arr_rows][arr_columns])
{
    int rows = arr_rows - 2;
    int columns = arr_columns - 2;
    int a[columns][rows];

    for (int k = 0; k < columns; k++)
    {
        int min_c = k;
        int max_c = k + 2;
        for (int l = 0; l < rows; l++)
        {
            int min_r = l;
            int max_r = l + 2;
            int sum = 0;
            for (int i = min_c; i <= max_c; i++)
            {
                if (max_c >= arr_columns)
                    break;
                for (int j = min_r; j <= max_r; j++)
                {
                    if (max_r >= arr_rows)
                        break;
                    if (i != min_c && i != max_c)
                    {
                        int no = j + 1;
                        sum += arr[i][no];
                        break;
                    }
                    sum += arr[i][j];
                }
            }
            a[k][l] = sum;
        }
    }
    int max = a[0][0];
    for (int b = 0; b < columns; b++)
    {
        for (int c = 0; c < rows; c++)
        {
            if (max < a[b][c])
                max = a[b][c];
        }
    }
    for (int i = 0; i < columns; i++)
    {
        for (int j = 0; j < rows; j++)
            printf(" %3d", a[i][j]);
        printf("\n");
    }
    return max;
}

int main(void)
{
    int arr[6][6];
    int arr_rows = 6;
    int arr_columns = 6;
    for (int i = 0; i < arr_columns; i++)
    {
        for (int j = 0; j < arr_rows; j++)
        {
            if (scanf("%d", &arr[i][j]) != 1)
            {
                fprintf(stderr, "failed to read an integer\n");
                return 1;
            }
        }
    }

    int result = hourglassSum(arr_rows, arr_columns, arr);
    printf("\n%d\n", result);
    return 0;
}

输出:

 -63 -34  -9  12
 -10   0  28  23
 -27 -11  -2  10
   9  17  25  18

28

请注意,这几乎是问题代码的最小修正。我自己的代码在很多方面都看起来有所不同(不同的变量名称,更多的函数等)。 另一项更改(上面没有做过):实际上不需要数组a;您可以在计算每个位置的沙漏总和后简单地记录当前的最大值。

对于alternative input

-1  1 -1  0  0  0
 0 -1  0  0  0  0
-1 -1 -1  0  0  0
 0 -9  2 -4 -4  0
-7  0  0 -2  0  0
 0  0 -1 -2 -4  0

我得到输出:

  -5  -2  -2   0
  -9 -13  -6  -8
 -19  -2  -7  -6
  -8 -14 -15 -14

0

这将产生您所期望的答案0(我同意0是应有的答案)。