이 포스트를 쓰게 된이유, 어떤 개쩌는 선생님이
너무잘 정리해 주셔서 블로그 글을 계속 들어가고 있는데
바로 이선생님이다.
C언어로 잘 정리 되어있꼬 그림도 있다.
2차원 배열에서 90도 회전 알고리즘
N * N 크기의 2차원 배열 전체를 시계방향으로 회전 시키는 방법은 생각보다 간단하다. 우선 이해를 돕기위해 1~25의 숫자를 가지는 5x5 크기의 2차원 배열을 그려 두었다. 회전 전후를 비교해서 보
velog.io
그런데 파이썬으로 정리가 안되어있어서 한번 내가 정리해보려고 글을 작성한다.
이글을 위해 vscode 를 킨다 !!!!!
먼저 2차원 배열이있다.
내가 원하는건 특정 부분만 잡고 돌리는것.
하지만 전체를 알아야 응용이 가능하다.
그래서 두가지 조건을 나눠보려고 한다.
1. 배열 전부다 돌리기
2. 특정 배열 부분(어디부터 어디까지만)
1. 배열 전부다 돌리기
먼저 배열 전부다 돌리는 방법이다.
위 배열을 시계 or 반시계 방향으로 돌린다면 ?
def clock_wise():
n = 5
temp = [ [0]*5 for _ in range(5) ]
for i in range(n) :
for j in range(n) :
temp[j][n-1-i]=maps[i][j]
for x in temp:
print(*x)
return
|
위와같은 for문을 쓰면된다. 은근 쉽다.
1번. for문을 쓴다.
2번. temp[j][i]=maps[i][j] 를 쓴다.
3번. 시계방향이면 i 부분에 n-1-i를 넣고, 반시계방향이면 j부분에 n-1-j를 넣는다.
아래는 시계방향으로 회전한 배열이다.
아래는 반시계방향으로 회전한 배열이다.
사실 배열 통째를 돌리는건 쉽다. 이제 부분적으로 잡아서 돌리는게 어렵다.
이제 부분적으로 잡아돌려보자.
위 블로그의 글을보면
왼쪽위 x,y 좌표와 얼마만큼 돌릴지를 정해야한다.
얼마만큼 돌릴지 = mid
왼쪽위 x,y 좌표를 함수 값으로 넣어야한다.
1번. for문을 length 로 쓴다. (*전체돌리는건 n(배열전체) 였으니 그걸 그대로 인용)
2번. 전체 돌리는거처럼 temp[j][i]=maps[i][j] 를 작성해준다.
그다음 전체 돌리는거하고 조금 다른부분이 나오는데
temp[x][y]와 arr[x][y] 해두고
temp[x+j][y+i]=arr[x+i][y+j] 이렇게 j,i를 맞게 더해준다음에 시계면 i쪽에 length-i-1+y 한다고생각하자.
*이거 제대로 디버깅안해서 문제풀다 틀렸따 꼭 외우기.
3번 원하는 부분에 시계 반시계를 넣어준다.
시계 방향이면 i부분에 [length-i-1+y] 를 넣고
반시계 방향이면 j 부분에 [length-j-1+x] 를 넣는다.
그렇게 다시쓰면
def check_rotate(x,y,length):
n = 5
temp = [ [0]*5 for _ in range(5) ]
for i in range(length):
for j in range(length):
temp[j+x][length-i+y-1] = maps[x+i][y+j]
print('check')
for x in temp:
print(*x)
return
|
이렇게 만들면 구현할 수있다.
0,0에서 길이 2를 돌린다.
근데 가끔 이런생각이든다.
x1,y1
x2,y2 두부분을 잡아서 돌릴수는 없나? ( 꼭 정사각형이여야함 )
그렇다면
0 0 0
0 1 1
0 1 1
이라고 한다면, 위함수라면 , rotate (1,1,2) 같이 할 수 있는데
func(1,1,2,2) 처럼 하고싶다면?(극한의 고집)
코드트리 해설을 보니 저렇게 두점을 돌렸엇다.
나도 문제를 풀며 구현해보려고했는데
저게 length-1-i+x << 할때 i앞에 마이너스가 들어가서 저부분이 문제가 발생했다. 그래서 뭔가 선처리를 해줘야하는데
def wow_rotate(x,y,x1,y1):
x1+=1
y1+=1
size = x1-x # 사이즈는 정사각형일때만 .
temp = [ [0]*5 for _ in range(5) ]
for i in range(x, x1):
for j in range(y, y1):
temp[j - y + x][size - i + x - 1 + y] = maps[i][j]
print('wow_check')
for x in temp:
print(*x)
return
|
이렇게 위와같이 해줘야 x,y부터 x1,y1까지만 시계방향으로돌릴수있다.
이제 이경우 안에있는 점화식을 보면 정신이 나갈꺼같은데..
솔직히 그냥
왼쪽위 , + 크기로 외우는게 훨씬편할꺼같다.
def check_rotate(x,y,length):
n = 5
temp = [ [0]*5 for _ in range(5) ]
for i in range(length):
for j in range(length):
temp[j+x][length-i+y-1] = maps[x+i][y+j]
print('check')
for x in temp:
print(*x)
return
|
잊지말자.
temp[j][i]=maps[i][j] 를 쓰고
temp[j+x][i+y]=maps[i+x][j+y] 를 써주고
시계방향이면 i쪽에 length+x-(i+1)
반시방향이면 j쪽에 length+y-(j+1)
이란것을...
이러면 쉽게 외울 수 있다 !!!
외우지말고 이해하면서 적어보면 안되나? 다시써보자.
'코딩 테스트' 카테고리의 다른 글
[코드트리챌린지] 재귀함수에 대한 고찰 - 파이썬 리뷰 (1) | 2023.10.10 |
---|---|
[2022 삼성 코딩테스트 상반기 오전 2번] 코드트리 - 팩맨 파이썬 리뷰 (1) | 2023.10.09 |
[2022 삼성 코딩테스트 상반기 오전 2번] 코드트리 - 예술성 파이썬 리뷰 (1) | 2023.10.06 |
[코드트리 챌린지] 2022 삼성 상반기 오전1번 코드트리 - 술래잡기 파이썬 (0) | 2023.10.05 |
[코드트리 챌린지] 정수 사각형 최소 합 (1) | 2023.10.04 |