1.useRef를 사용해 처음 값을 넣어줄 경우 .current의 default가 되며
.current의 값을 수정 및 조회할 수 있다.

useRef를 굳이 사용하는 가장 큰 이유는
리렌더링에 영향을 받지 않고 변수를 저장할 수 있다는 것이다.

아무래도 useState와 유사한 작동원리를 가지고
리액트의 전역 저장소에 저장되기 때문에
render()의 기능만 제거했을 뿐 값이 변하지 않고 저장되는 것 같다.


2.onClick 등의 메서드에 함수를 넣어줄 경우
매개변수를 바로 넣을 수 없는 문제가 발생하는데
onClick={functionName(data)}와 같은 함수를 사용하면 안되고
onClick={()=>{functionName(data)}는 가능한 이유는
실행 시점의 여부에 달려있다.

functionName(data)는 사실 매개변수가 들어간 functionName()과 다를게 없고
그렇다는 말은 저 함수를 즉시 실행하라는 명령인 것이다.

그렇기 때문에 저 함수를 실행할 함수를 한번 씌워주는 함수가 필요하고
그것을 간략하게 줄일 수 있는 것이 ArrowFunction이다.

 

 

 

 

 

(1).백준 1018 체스판 다시 칠하기는 검정/흰색으로 칠해진 큰 보드를 잘라
8x8사이즈의 체스판을 만들려고 할 때
체스판으로 보이기 위해 색칠해야 하는 최저 칸 수를 구하는 문제였다.

체스판을 만들어야 한다

각 좌표별로 시작점이 흰색 또는 검은색이 될 경우
인접한 칸은 검은색 또는 흰색의 순서로 진행되야 하기 때문에
아래와 같은 형태로 색이 비교되야 한다.

흰검흰검흰검흰검     검흰검흰검흰검흰
검흰검흰검흰검흰     흰검흰검흰검흰검
흰검흰검흰검흰검     검흰검흰검흰검흰
검흰검흰검흰검흰     흰검흰검흰검흰검
흰검흰검흰검흰검     검흰검흰검흰검흰
검흰검흰검흰검흰     흰검흰검흰검흰검
흰검흰검흰검흰검     검흰검흰검흰검흰
검흰검흰검흰검흰     흰검흰검흰검흰검

이걸 잘 생각해보면 x,y좌표값을 받았을 때
인접한 칸은 x,y의 합이 1 차이날 수 밖에 없고
그 칸의 인접칸은 다시 1이 차이나는 것을 볼 수 있다.

i+j가 1일 경우 %2로 처리하면 10101010의 순서고

i+j가 0일 경우 %2로 처리하면 01010101의 순서임을 알 수 있다.

i+j i+j+1 i+j+2 i+j+3 i+j+4 i+j+5 i+j+6 i+j+7
i+j+1 i+j+2 i+j+3 i+j+4 i+j+5 i+j+6 i+j+7 i+j+8
i+j+2 i+j+3 i+j+4 i+j+5 i+j+6 i+j+7 i+j+8 i+j+9
i+j+3 i+j+4 i+j+5 i+j+6 i+j+7 i+j+8 i+j+9 i+j+10
i+j+4 i+j+5 i+j+6 i+j+7 i+j+8 i+j+9 i+j+10 i+j+11
i+j+5 i+j+6 i+j+7 i+j+8 i+j+9 i+j+10 i+j+11 i+j+12
i+j+6 i+j+7 i+j+8 i+j+9 i+j+10 i+j+11 i+j+12 i+j+13
i+j+7 i+j+8 i+j+9 i+j+10 i+j+11 i+j+12 i+j+13 i+j+14

 

이러한 원리를 이용해
(x+y)%2로 들어가야 할 값이 흰색인지 검은색인지를 0/1로 구분하고
색칠해야 하는 값을 구할 수 있었다.

하지만 이렇게 하면 시작점이 흰색/검은색은 첫 좌표에 따라 달라지기 때문에
두가지를 모두 체크하기 위해 두번 계산하지 않고
색의 반대임을 이용해 Math.min에 64-result와 result를 넣어 비교했다.

이렇게 나온 결고값을 계속 최소비용값과 비교해
최소가 나올 경우 교체하는 방식으로 진행했으며
여기서 만약 비용 0이 나올 경우 return하는 것도 좋을 것 같다.

const input = `11 12
BWWBWWBWWBWW
BWWBWBBWWBWW
WBWWBWBBWWBW
BWWBWBBWWBWW
WBWWBWBBWWBW
BWWBWBBWWBWW
WBWWBWBBWWBW
BWWBWBWWWBWW
WBWWBWBBWWBW
BWWBWBBWWBWW
WBWWBWBBWWBW`.split('\n')

const [boardSizeX, boardSizeY] = input[0].split(' ').map(Number)
const baseBoard = input.slice(1)
let minCost = 64
const boardColorChecker = (x,y) => {
    let WrongColorCount = 0
    for(let i = x ; i < x+8 ; i++){
        for(let j = y ; j < y+8 ; j++){
            if((i+j)%2 === 1 && baseBoard[i][j] === 'B'){
                WrongColorCount++
            }
            else if((i+j)%2 === 0 && baseBoard[i][j] === 'W'){
                WrongColorCount++
            }
        }
    }
    return Math.min(WrongColorCount, 64-WrongColorCount)
}

for(let i = 0 ; i <= boardSizeX-8 ; i++){
    for(let j = 0 ; j <= boardSizeY-8 ; j++){
        minCost = Math.min(minCost, boardColorChecker(i,j))
    }
}

console.log(minCost)

 

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

위 문제에서 조건 달성시 return을 바로 써주고 싶었지만
출력하는 문제기 때문에 불가능했고
이중 for문을 벗어날 수 있는 방법을 알고 싶었다.

검색해보니 아래와 같이 for문, while문 등에 이름을 부여한 다음
break 또는 continue 뒤에 지정한 이름을 붙여주면 
이름에 맞는 for문 또는 while문에 해당 동작을 시행한다.

 

아래의 예시와 같이 for문 내부에서 break를 작동시키면 내부에서만 중단되기 때문에

의도한 것과 다른 일이 발생할 가능성이 높다.

for(let i = 0 ; i < 4 ; i++){
    for(let j = 0 ; j < 4 ; j++){
        console.log(`nomal break i = ${i} nomal j = ${j}`)
        if(j === 2){
            break
        }
    }
}
// j가 2가 되면 해당 스코프의 for문을 중단시키기 때문에 j = 3은 출력되지 않는 것을 볼 수 있다.
// nomal break i = 0 nomal j = 0
// nomal break i = 0 nomal j = 1
// nomal break i = 0 nomal j = 2
// nomal break i = 1 nomal j = 0
// nomal break i = 1 nomal j = 1
// nomal break i = 1 nomal j = 2
// nomal break i = 2 nomal j = 0
// nomal break i = 2 nomal j = 1
// nomal break i = 2 nomal j = 2
// nomal break i = 3 nomal j = 0
// nomal break i = 3 nomal j = 1
// nomal break i = 3 nomal j = 2

 

하지만 for문에 태그를 붙여준다면 내부에서도 접근이 가능하고

조건 달성 시 외부 for문을 종료시켜 조건이 달성된 3회만에 작업이 종료되는 것을 볼 수 있다.

outer : for(let i = 0 ; i < 4 ; i++){
    for(let j = 0 ; j < 4 ; j++){
        console.log(`outer break i = ${i} nomal j = ${j}`)
        if(j === 2){
            break outer
        }
    }
}
// j가 2가 되면 외부 for문을 중단시키기 때문에 출력이 멈추는 것을 볼 수 있다.
// outer break i = 0 nomal j = 0
// outer break i = 0 nomal j = 1
// outer break i = 0 nomal j = 2

 

또한 continue를 사용하면 상위 for문(여기서는 outer)에 접근해

바로 다음으로 넘어가게 하는 것을 볼 수 있다.

outer : for(let i = 0 ; i < 4 ; i++){
    for(let j = 0 ; j < 4 ; j++){
        console.log(`outer continue i = ${i} nomal j = ${j}`)
        if(j === 2){
            continue outer
        }
    }
    console.log("continue가 작동되면 출력되지 않는다.")
}
// j가 2가 되면 다음 i로 넘어가기 때문에 j = 3은 출력되지 않고 
// continue 하단에 위치한 "continue가 작동되면 출력되지 않는다" 또한 출력되지 않는 것을 볼 수 있다.
// outer continue i = 0 nomal j = 0
// outer continue i = 0 nomal j = 1
// outer continue i = 0 nomal j = 2
// outer continue i = 1 nomal j = 0
// outer continue i = 1 nomal j = 1
// outer continue i = 1 nomal j = 2
// outer continue i = 2 nomal j = 0
// outer continue i = 2 nomal j = 1
// outer continue i = 2 nomal j = 2
// outer continue i = 3 nomal j = 0
// outer continue i = 3 nomal j = 1



이런 방식을 통해 조금 더 최적화를 할 수 있었다.

const input = `11 12
BWWBWWBWWBWW
BWWBWBBWWBWW
WBWWBWBBWWBW
BWWBWBBWWBWW
WBWWBWBBWWBW
BWWBWBBWWBWW
WBWWBWBBWWBW
BWWBWBWWWBWW
WBWWBWBBWWBW
BWWBWBBWWBWW
WBWWBWBBWWBW`.split('\n')

const [boardSizeX, boardSizeY] = input[0].split(' ').map(Number)
const baseBoard = input.slice(1)
let minCost = 64
const boardColorChecker = (x,y) => {
    let WrongColorCount = 0
    for(let i = x ; i < x+8 ; i++){
        for(let j = y ; j < y+8 ; j++){
            if((i+j)%2 === 1 && baseBoard[i][j] === 'B'){
                WrongColorCount++
            }
            else if((i+j)%2 === 0 && baseBoard[i][j] === 'W'){
                WrongColorCount++
            }
        }
    }
    return Math.min(WrongColorCount, 64-WrongColorCount)
}

outer : for(let i = 0 ; i <= boardSizeX-8 ; i++){
    for(let j = 0 ; j <= boardSizeY-8 ; j++){
        minCost = Math.min(minCost, boardColorChecker(i,j))
    }
    if(minCost === 0){
        break outer
    }
}

console.log(minCost)

'회고' 카테고리의 다른 글

[취업준비일지] - 105  (0) 2023.02.02
[취업준비일지] - 104  (0) 2023.02.01
[취업준비일지] - 102  (0) 2023.01.30
[취업준비일지] - 101  (0) 2023.01.29
[취업준비일지] - 100  (0) 2023.01.28

+ Recent posts