【问题标题】:how to print a matrix with a negated row more efficiently如何更有效地打印具有否定行的矩阵
【发布时间】:2021-05-10 00:42:12
【问题描述】:

我写了以下函数:

void negate_row(const int n, const int r, int *a)
{
    if (r == 0)
    {
        printf("Matrix with negated row: ");
        printf("\n");
        for (int y = 0; y < 3; y++)
        {
            *(a + 3 * r + y) = *(a + 3 * r + y) *(-1);
            printf("%d ", *(a + 3 * r + y));
        }
        printf("\n");

        for (int y = 0; y < 3; y++)
        {
            *(a + 3 * r + y) = *(a + 3 * r + y) *(-1);
            printf("%d ", *(a + 3 * (r + 1) + y));
        }
        printf("\n");

        for (int y = 0; y < 3; y++)
        {
            *(a + 3 * r + y) = *(a + 3 * r + y) *(-1);
            printf("%d ", *(a + 3 * (r + 2) + y));
        }
        printf("\n");
    }

所以基本上这里发生的是我的函数接受一个 n X 3 矩阵并使用指针算术否定特定行。我已经能够做到这一点,我还能够弄清楚如何用否定行打印相同的矩阵。这只是我这样做的方式根本没有效率。我必须为每一行编写一个 if 语句,例如 if r == 0,1,2,3,4 等...有什么办法可以更有效地做到这一点?

一些说明:const int n 决定矩阵的大小 (n x 3),const int r 决定取反的行 (0 r n)。

【问题讨论】:

    标签: c multidimensional-array printf pointer-arithmetic function-definition


    【解决方案1】:

    第二个循环会有所帮助。我通常发现指针代码有点难以阅读。特别是对于矩阵操作,您最好使用数组语法而不是指针语法。

    for (int y = 0; y < 3; y++)
    {
        for (int x = 0; x < 3; x++)
        {
            printf("%d ", *(a + 3 * (r + x) + y));
        }
    
        printf("\n");
    }
    

    【讨论】:

    • 他有n 列所以它是x &lt; n
    • x 循环应该是外循环。
    • 是的。你们是对的。我只是在解决如何在他的一个循环中减少重复代码的问题。这似乎就是问题所在。
    • 感谢您的回答,它确实有效。但是有一个问题,这就是我所面临的,以及为什么我做了我所做的解决方案。根据输入要否定的行,该行将打印为矩阵的第一行。这就是它的意思,选择的行应该保留在原来的位置。例如,如果选择了第 2 行,它不应该成为第 0 行,它应该保留在第 2 行的位置。
    【解决方案2】:

    特殊情况(3行):

    int mul = 1, y = 0;
    for (int x = 0; x < n; x++) {
        mul = x == r ? -1 : 1;
        y = (a + 3 * x);
        printf("%d ", (*y) * mul);
        printf("%d ", (*y + 1) * mul);
        printf("%d ", (*y + 2) * mul);
        printf("\n");
    }
    

    更通用(m 行):

    int mul = 1;
    for (int x = 0; x < n; x++) {
        mul = x == r ? -1 : 1;
        for (int y = 0; y < m; y++) {
          printf("%d ", ((*(a + m * x + y)) * mul);
        }
        printf("\n");
    }
    

    注意:在新的编译器中,数组或指针语法在速度上也没有区别。

    【讨论】:

      【解决方案3】:

      您可以编写一个接受一维数组(矩阵的一行)的函数,然后使用此函数您可以循环输出其所有行或输出选定的行。

      这是一个演示程序。

      #include <stdio.h>
      
      void negate_row( const int *a, size_t n, int width )
      {
          if ( width < 1 ) width = 1;
          
          for ( const int *p = a; p != a + n; ++p )
          {
              printf( "%*d ", width, -*p );
          }
          putchar( '\n' );
      }
      
      int main(void) 
      {
          enum { M = 3, N = 4 };
          int matrix[M][N] =
          {
              { 0,  1,  2,  4 },
              { 5,  6,  7,  8 },
              { 9, 10, 11, 12 }
          };
          
          for ( int ( *p )[N] = matrix; p != matrix + M; ++p )
          {
              negate_row( *p, N, 3 );
          }
          
          return 0;
      }
      

      程序输出是

        0  -1  -2  -4 
       -5  -6  -7  -8 
       -9 -10 -11 -12 
      

      正如您展示的代码,您使用指针 tp 输出数组元素,然后在这个演示程序中,我还在各处使用指针来访问数组元素。

      函数的第三个参数指定输出值的字段宽度。

      要以行的相反顺序输出矩阵,您可以使用程序中显示的循环。

      #include <stdio.h>
      
      void negate_row( const int *a, size_t n, int width )
      {
          if ( width < 1 ) width = 1;
          
          for ( const int *p = a; p != a + n; ++p )
          {
              printf( "%*d ", width, -*p );
          }
          putchar( '\n' );
      }
      
      int main(void) 
      {
          enum { M = 3, N = 4 };
          int matrix[M][N] =
          {
              { 0,  1,  2,  4 },
              { 5,  6,  7,  8 },
              { 9, 10, 11, 12 }
          };
          
          for ( int ( *p )[N] = matrix + M; p != matrix;  )
          {
              negate_row( *--p, N, 3 );
          }
          
          return 0;
      }
      

      程序输出是

       -9 -10 -11 -12 
       -5  -6  -7  -8 
        0  -1  -2  -4 
      

      【讨论】:

        【解决方案4】:

        您可以轻松地概括该函数:只要行在矩阵内,您的代码就适用于任何行。另请注意,最好使用单独的函数来打印矩阵。

        #include <stdio.h>
        
        void negate_row(const int n, const int r, int *a) {
            if (r >= 0 && r < n) {
                // negate row r
                for (int col = 0; col < 3; col++) {
                    *(a + 3 * r + col) *= -1;
                }
            }
        }
        
        void print_matrix(const int n, int *a, const char *title) {
            if (title) {
                printf("%s:\n", title);
            }
            for (int row = 0; row < n; row++) {
                for (int col = 0; col < 3; col++) {
                    printf("%d ", *(a + 3 * row + col));
                }
                printf("\n");
            }
            printf("\n");
        }
        
        int main() {
            int matrix[5 * 3] = {
                0, 1, 2,
                3, 4, 5,
                6, 7, 8,
                9, 10, 11,
                12, 13, 14,
            };
            print_matrix(5, matrix, "Matrix");
            negate_row(5, 0, matrix);
            print_matrix(5, matrix, "Matrix with negated row");
            negate_row(5, 3, matrix);
            print_matrix(5, matrix, "Matrix with two negated rows");
            negate_row(5, 0, matrix);
            negate_row(5, 3, matrix);
            print_matrix(5, matrix, "Matrix back to origin");
            return 0;
        } 
        

        输出:

        矩阵: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 具有否定行的矩阵: 0 -1 -2 3 4 5 6 7 8 9 10 11 12 13 14 具有两个否定行的矩阵: 0 -1 -2 3 4 5 6 7 8 -9 -10 -11 12 13 14 矩阵回原点: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-11-28
          • 2020-09-08
          • 1970-01-01
          • 2011-03-07
          • 2017-02-19
          • 1970-01-01
          相关资源
          最近更新 更多