Вращатель массива на месте, возвращающий неправильные значения

#python #algorithm #array-algorithms

#python #алгоритм #массив-алгоритмы

Вопрос:

Я хочу определить функцию для поворота матрицы на 90 градусов на месте

 def rotate_matrix(matrix):
        for i in range(len(matrix)//2):
            for j in range(i, len(matrix)-i-1):
                matrix[~j][i], matrix[i][j], matrix[j][~i], matrix[~i][~j] = matrix[i][j], matrix[j][~i], matrix[~i][~j], matrix[~j][i]
        return matrix
  

При установке :

 [
 [a, b],
 [c, d]
]
  

он возвращает:

 [
 [b, d],
 [a, c]
]
  

вместо:

 [
 [c, a],
 [d, b]
]
  

и я не уверен, почему.

Ответ №1:

Вы были на правильном пути! Ваш код выполняет вращение против часовой стрелки вместо часовой.
Чтобы решить эту проблему, вам нужно внести несколько небольших изменений в логику назначения:

 def rotate_matrix(matrix):
        for i in range(len(matrix)//2):
            for j in range(i, len(matrix)-i-1):
                matrix[~j][i], matrix[i][j], matrix[j][~i], matrix[~i][~j] = 
                matrix[~i][~j], matrix[~j][i], matrix[i][j], matrix[j][~i]
        return matrix
  

делает то, что вы ищете.


Однако я бы использовал numpy, поскольку у него есть встроенный метод для поворота матриц:

 import numpy as np
mat = np.array([['a','b'],
         ['c','d']])

def rotate_matrix(matrix):
    return np.rot90(matrix, 3) // * SEE NOTE

print(rotate_matrix(mat))
  

ВОЗВРАТ:

 [['c' 'a']
 ['d' 'b']]
  

ПРИМЕЧАНИЕ: метод rot90 предлагает вращение против часовой стрелки. Поскольку вы запрашиваете вращение по часовой стрелке, вы должны указать аргумент 3, чтобы указать количество вращений против часовой стрелки, которые необходимо выполнить для достижения вращения по часовой стрелке.

Ответ №2:

это решение вашей проблемы, вы должны использовать правильное значение присваивания

попытайтесь увидеть назначение, которое вы выполняете,

с точки зрения индекса : (0,0) —> (0,1) , (0,1) —> (1,1), (1,0) —>(0,0) и (1,1) —> (1,0) это неправильно .

вот почему вы получаете неправильное решение

что вам нужно было сделать, так это сопоставить индекс как

(0,0) —>(0,1) , (0,1)—>(0,0) , (1,1)—>(0,1),(1,0)—>(1,1)

ниже приведено правильное решение.

 def rotate_matrix(matrix):
        for i in range(len(matrix)//2):
            for j in range(i, len(matrix)-i-1):
               matrix[i][j], matrix[~i][j], matrix[i][~j], matrix[~i][~j]= matrix[~i][j],matrix[i][~j],matrix[i][j],matrix[~i][~j]
        return matrix

a = [
 ['a','b'],
 ['c', 'd']
]

print(rotate_matrix(a))
# output [['c', 'a'], ['b', 'd']]
  

это решение проблемы, которую вы пытаетесь решить, то есть поворот матрицы
под углом 90 градусов
# Программа на Python для поворота матрицы

 # Function to rotate a matrix 
def rotateMatrix(mat): 

    if not len(mat): 
        return

    """ 
        top : starting row index 
        bottom : ending row index 
        left : starting column index 
        right : ending column index 
    """

    top = 0
    bottom = len(mat)-1

    left = 0
    right = len(mat[0])-1

    while left < right and top < bottom: 

        # Store the first element of next row, 
        # this element will replace first element of 
        # current row 
        prev = mat[top 1][left] 

        # Move elements of top row one step right 
        for i in range(left, right 1): 
            curr = mat[top][i] 
            mat[top][i] = prev 
            prev = curr 

        top  = 1

        # Move elements of rightmost column one step downwards 
        for i in range(top, bottom 1): 
            curr = mat[i][right] 
            mat[i][right] = prev 
            prev = curr 

        right -= 1

        # Move elements of bottom row one step left 
        for i in range(right, left-1, -1): 
            curr = mat[bottom][i] 
            mat[bottom][i] = prev 
            prev = curr 

        bottom -= 1

        # Move elements of leftmost column one step upwards 
        for i in range(bottom, top-1, -1): 
            curr = mat[i][left] 
            mat[i][left] = prev 
            prev = curr 

        left  = 1

    return mat 

# Utility Function 
def printMatrix(mat): 
    for row in mat: 
        print row 


# Test case 1 
matrix = [
 ['a','b'],
 ['c', 'd']
]



matrix = rotateMatrix(matrix) 
# Print modified matrix 
printMatrix(matrix) 

# output [['c', 'a'], ['b', 'd']]
  

ps второе решение, которое справляется с geeksforgeets

Комментарии:

1. @DanielPahor Я опубликовал правку с исправлением вашего исходного алгоритма. Ваша логика назначения перевернута, поэтому матрицы поворачиваются не в ту сторону. Если этого недостаточно, пожалуйста, отредактируйте свой вопрос, чтобы сделать запрос более четким.

2. @DanielPahor попытайтесь увидеть выполняемое вами присвоение в терминах индекса (0,0) с (0,1) , (0,1)-> (1,1), (1,0) ->(0,0) и (1,1) -> (1,0) это неправильно . вот почему вы получаете неправильное решение