有人可以在我的矩阵旋转代码中找到错误吗?

Posted

技术标签:

【中文标题】有人可以在我的矩阵旋转代码中找到错误吗?【英文标题】:Can someone find the bug in my code for Matrix Rotation? 【发布时间】:2015-08-16 10:06:22 【问题描述】:

我正在尝试进行hackerrank Matrix Rotation 挑战。我的代码中有一个我找不到的错误。该代码应该将测试矩阵的所有外部和内部循环旋转 r 次(1 = (r % number_of _elements_in_outer_loop) 的测试用例中失败。我找不到错误。提前感谢您的任何回复。以下是代码(在 Visual Studio 2015 中测试)。有要求的hackerrank挑战是here

// MatrixRotation.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>

using namespace std;

int main()

//  int i, j, k;
    int m, n, r;
    int rotations, rot;
    int m_start, m_end, m_len;
    int n_start, n_end, n_len;
    int m_curr, n_curr;

//-------------------------------------------------------------------------
// For hackerrank testing
//-------------------------------------------------------------------------

    int i, j;

    for (i = 1; i <= 3; i++)
    

        if (i == 1) std::cin >> m;
        else if (i == 2) std::cin >> n;
        else std::cin >> r;

    

    int **matrix = new int*[m];
    for (int i = 0; i < m; ++i) 
        matrix[i] = new int[n];
    

    for (i = 0; i < m; i++)
        for (j = 0; j < n; j++)
            std::cin >> matrix[i][j];


    //-------------------------------------------------------------------------
    // For local machine in Visual Studio testing
    //-------------------------------------------------------------------------

    /*

    int i, j, k;

    m = 10;
    n = 8;
    r = 40;

    int **matrix = new int*[m];
    for (int i = 0; i < m; ++i) 
        matrix[i] = new int[n];
    

    k = 1;
    for (i = 0; i < m; i++)
        for (j = 0; j < n; j++)
        
            matrix[i][j] = k;
            k += 1;
        

    for (i = 0; i < m; i++)
        for (j = 0; j < n; j++)
        
            std::cout << matrix[i][j] << " ";

            if (j == n - 1)
                std::cout << endl;

        

    std::cout << endl;

    */

    //-------------------------------------------------------------------------
    // Begin computations
    //-------------------------------------------------------------------------

    int outer_loop_rotation;

    outer_loop_rotation = (n - 1)  + (m - 1) + (n - 1) + (m - 1)  ;

    rot = r % outer_loop_rotation;

//  std::cout << endl << endl << "outer loop rotation = " << outer_loop_rotation << endl << endl << "rot = " << rot << endl << endl;

    for (rotations = 1; rotations <= rot; rotations++)
    

        m_start = 0;
        m_end = m - 1;

        n_start = 0;
        n_end = n - 1;

        m_len = m_end - m_start;
        n_len = n_end - n_start;


        // Following while loop is 1 rotation for all loops

        while (m_len >= 1 && n_len >= 1)
        

            int loop_start = matrix[m_start][n_start];

            // Following for loop is for row start

            m_curr = m_start;
            n_curr = n_start;

            for (i = 1; i <= n_len  ; i++)
            

                matrix[m_curr][n_curr] = matrix[m_curr][n_curr + 1];
                n_curr += 1;

            

            // Following for loop is for col end

            m_curr = m_start;
            n_curr = n_end;

            for (i = 1; i <= m_len  ; i++)
            

                matrix[m_curr][n_curr] = matrix[m_curr + 1][n_curr];
                m_curr += 1;

            

            // Following for loop is for row end

            m_curr = m_end;
            n_curr = n_end;

            for (i = 1; i <= n_len  ; i++)
            

                matrix[m_curr][n_curr] = matrix[m_curr][n_curr - 1];
                n_curr -= 1;

            

            // Following for loop is for col start

            m_curr = m_end;
            n_curr = n_start;

            for (i = 1; i <= m_len   ; i++)
            
                if (i < m_len )
                
                    matrix[m_curr][n_curr] = matrix[m_curr - 1][n_curr];
                    m_curr -= 1;


                

                else
                

                    matrix[m_curr][n_curr] = loop_start;


                

            

            m_start += 1;
            m_end -= 1;

            n_start += 1;
            n_end -= 1;

            m_len = m_end - m_start;
            n_len = n_end - n_start;


         // End while loop

     // End for loop

    // End computations, now output to command line

    for (i = 0; i < m; i++)
        for (j = 0; j < n; j++)
        
            std::cout << matrix[i][j] << " ";

            if (j == n - 1)
                std::cout << endl;

        


    return 0;

【问题讨论】:

Hackerrank 挑战链接:hackerrank.com/challenges/matrix-rotation-algo/copy-from/… 如果你在挑战中运行我的代码,那么你必须在代码开头注释掉#include "stdafx.h"。 您应该将每个循环旋转 r 个位置,或者在优化之后,r % number_of_positions_in_this_loop 个位置。 【参考方案1】:

我认为错误在于您只为整个矩阵计算一次模值,对应于旋转最外层的循环重复长度。但是,矩阵中的每一层都将具有不同的循环长度。例如,最外层的重复周期长度,正如您计算的那样,是:

(n - 1)  + (m - 1) + (n - 1) + (m - 1)

但是,对于倒数第二层,重复长度为:

(n - 3)  + (m - 3) + (n - 3) + (m - 3)

或更一般地

((n - ((layer*2)+1))  + (m - ((layer*2)+1))) * 2

其中最外层为 0,倒数第二个为 1,以此类推

因此,您需要更改代码以计算每一层的模数,而不是计算整个矩阵的一次。

【讨论】:

谢谢。这就是我的想法,但我不确定。如果可行,我会将您的答案标记为已接受。 谢谢。那行得通。我不得不交换外部的“for”和“while”循环以使其工作。我会将您的答案标记为已接受的解决方案。【参考方案2】:

这是最终的有效代码,以防有人感兴趣。

  // MatrixRotation.cpp : Defines the entry point for the console application.
  //

#include "stdafx.h"
#include <iostream>

using namespace std;

int main()

//  int i, j, k;
    int m, n, r;
    int rotations, rot;
    int loop_decrement, loop_rotation;
    int m_start, m_end, m_len;
    int n_start, n_end, n_len;
    int m_curr, n_curr;

//-------------------------------------------------------------------------
// For hackerrank testing
//-------------------------------------------------------------------------

    int i, j;

    for (i = 1; i <= 3; i++)
    

        if (i == 1) std::cin >> m;
        else if (i == 2) std::cin >> n;
        else std::cin >> r;

    

    int **matrix = new int*[m];
    for (int i = 0; i < m; ++i) 
        matrix[i] = new int[n];
    

    for (i = 0; i < m; i++)
        for (j = 0; j < n; j++)
            std::cin >> matrix[i][j];


    //-------------------------------------------------------------------------
    // For local machine in Visual Studio testing
    //-------------------------------------------------------------------------

/*  

    int i, j, k;

    m = 4;
    n = 4;
    r = 2;

    int **matrix = new int*[m];
    for (int i = 0; i < m; ++i) 
        matrix[i] = new int[n];
    

    k = 1;
    for (i = 0; i < m; i++)
        for (j = 0; j < n; j++)
        
            matrix[i][j] = k;
            k += 1;
        

    for (i = 0; i < m; i++)
        for (j = 0; j < n; j++)
        
            std::cout << matrix[i][j] << " ";

            if (j == n - 1)
                std::cout << endl;

        

    std::cout << endl;

    */

    //-------------------------------------------------------------------------
    // Begin computations
    //-------------------------------------------------------------------------

    m_start = 0;
    m_end = m - 1;

    n_start = 0;
    n_end = n - 1;

    m_len = m_end - m_start;
    n_len = n_end - n_start;


    // Following while loop is all rotations
    // for all loops one loop at a time

    loop_decrement = 1;

    while (m_len >= 1 && n_len >= 1)
    
        // loop_rotation = number of items in current loop

        loop_rotation = (n - loop_decrement) + (m - loop_decrement) + (n - loop_decrement) + (m - loop_decrement);

        rot = r % loop_rotation;

        for (rotations = 1; rotations <= rot; rotations++)
        

            int loop_start = matrix[m_start][n_start];

            // Following for loop is for top row in current loop

            m_curr = m_start;
            n_curr = n_start;

            for (i = 1; i <= n_len  ; i++)
            

                matrix[m_curr][n_curr] = matrix[m_curr][n_curr + 1];
                n_curr += 1;

            

            // Following for loop is for right col in current loop

            m_curr = m_start;
            n_curr = n_end;

            for (i = 1; i <= m_len  ; i++)
            

                matrix[m_curr][n_curr] = matrix[m_curr + 1][n_curr];
                m_curr += 1;

            

            // Following for loop is for bottom row in current loop

            m_curr = m_end;
            n_curr = n_end;

            for (i = 1; i <= n_len  ; i++)
            

                matrix[m_curr][n_curr] = matrix[m_curr][n_curr - 1];
                n_curr -= 1;

            

            // Following for loop is for left col in current loop

            m_curr = m_end;
            n_curr = n_start;

            for (i = 1; i <= m_len   ; i++)
            
                if (i < m_len )
                
                    matrix[m_curr][n_curr] = matrix[m_curr - 1][n_curr];
                    m_curr -= 1;


                

                else
                

                    matrix[m_curr][n_curr] = loop_start;


                

            

         // End for loop

        m_start += 1;
        m_end -= 1;

        n_start += 1;
        n_end -= 1;

        m_len = m_end - m_start;
        n_len = n_end - n_start;

        loop_decrement += 2;

     // End while loop

    // End computations, now output to command line

    for (i = 0; i < m; i++)
        for (j = 0; j < n; j++)
        
            std::cout << matrix[i][j] << " ";

            if (j == n - 1)
                std::cout << endl;

        


    return 0;

【讨论】:

以上是关于有人可以在我的矩阵旋转代码中找到错误吗?的主要内容,如果未能解决你的问题,请参考以下文章

旋转矩阵到带角度的向量

计算大数据的相异矩阵

有人可以帮我修复错误 pls-00049 吗?

将矩阵旋转到位

旋转+矩阵+JSFL

尝试连接时 Chromecast 给出错误代码 7