신나는 알고리즘 풀이 시간.
오늘 풀어본 문제는 문자열을 이진 변환으로 반복 처리하는 알고리즘 문제였다.
0과 1로 구성된 문자열을 가공하고, 이를 기반으로 조건에 맞는 반복 처리를 설계하는 문제로, 문자열 조작과 반복문 활용 능력을 요구했다.
이번 글에서는 문제 풀이 과정을 정리하며, 작성한 코드와 주요 로직을 소개한다.
문제 설명
이진 변환이란?
- 문자열에서 모든 '0'을 제거한다.
- 변환된 문자열의 길이를 2진법으로 표현하여 문자열로 바꾼다.
이 과정을 문자열이 "1"이 될 때까지 반복하며, 다음 정보를 구한다:
- 변환 횟수
- 제거된 '0'의 총 개수
문제 풀이
핵심 접근
- 반복 처리
- 문자열이 "1"이 될 때까지 반복한다.
- 0 제거
- 문자열에서 '0'을 제거하며, 제거된 개수를 누적한다.
- 2진 변환
- 문자열의 길이를 구한 뒤, 이를 2진법 문자열로 변환한다.
코드 구현
function solution(s) {
let answer = [];
let zeroCount = 0;
let changeCount = 0;
while (s !== "1") {
let newS = s.replace("0", "");
if (newS.length < s.length) {
zeroCount++;
}
s = newS;
if (!s.includes("0")) {
s = s.length.toString(2);
changeCount++;
}
}
answer.push(changeCount);
answer.push(zeroCount);
return answer;
}
solution("01110");
// let decimal = 10;
// let binary = decimal.toString(2);
// console.log(binary);
코드 설명
- 초기화
- zeroCount: 제거된 '0'의 총 개수를 저장.
- changeCount: 이진 변환이 실행된 횟수를 저장.
- 반복 처리
- while (s !== "1"): 문자열이 "1"이 될 때까지 반복.
- 0 제거와 개수 누적
- let newS = s.replace("0", ""): 문자열에서 '0'을 제거.
- if (newS.length < s.length) {zeroCount++} : 제거된 개수 계산
트러블슈팅
문제 1: 잘못된 0의 개수 계산
처음에는 '0'을 제거할 때마다 zeroCount를 증가시켰다.
그러나 '0'이 없는 경우에도 zeroCount가 증가하는 문제가 발생.
해결
문자열 길이를 비교하여 '0'이 제거된 개수만 정확히 누적
let newS = s.replace("0", "");
if (newS.length < s.length) {
zeroCount++;
}
리액트 심화 프로젝트 캠핑 사이트.
프로젝트 트러블슈팅: 웹사이트 개발 중 해결한 문제들
1. 카카오맵 출력 문제
문제:
카카오맵이 제대로 렌더링되지 않음.
원인:
- geoData 상태가 초기화되지 않거나 null 상태로 유지.
- 카카오맵 SDK가 비동기적으로 로드되기 전에 맵 컴포넌트가 렌더링됨.
- NEXT_PUBLIC_KAKAO_MAP_API_KEY 환경 변수가 누락되거나 잘못 설정됨.
해결 방법:
- 기본 좌표를 설정하여 위치 정보가 없더라도 맵이 출력되도록 처리.
- SDK 로드 여부를 확인하기 위해 isSdkLoaded 상태를 추가.
const [isSdkLoaded, setIsSdkLoaded] = useState(false);
useEffect(() => {
const checkSdkLoaded = () => {
if (window.kakao && window.kakao.maps) {
setIsSdkLoaded(true);
}
};
const interval = setInterval(checkSdkLoaded, 100);
return () => clearInterval(interval);
}, []);
2. 마커 클릭 시 모든 오버레이가 표시되는 문제
문제:
마커를 클릭하면 해당 마커의 오버레이뿐만 아니라 다른 마커들의 오버레이도 표시됨.
원인:
- selectedMarker와 비교할 때 객체 참조 문제 발생.
해결 방법:
- 마커의 고유한 값을 비교하도록 조건 수정:
radiusCampList!.map((list) => (
<MapMarker
key={`${list.facltNm}-${{ lat: list.mapY, lng: list.mapX }}`}
position={{ lat: Number(list.mapY), lng: Number(list.mapX) }} // 마커를 표시할 위치
image={{
src: '/images/custom_marker.png',
size: {
width: 35,
height: 35,
}, // 마커이미지의 크기입니다
}}
title={list.facltNm} // 마커의 타이틀, 마커에 마우스를 올리면 타이틀이 표시됩니다
onClick={() => setSelectedMarker(list)}
/>
))
radiusCampList!.map((list) => {
if (selectedMarker === list) {
return (
<CustomOverlayMap
key={`${list.facltNm}-${{ lat: list.mapY, lng: list.mapX }}`}
position={{ lat: Number(list.mapY), lng: Number(list.mapX) }}
>
<div className="flex flex-col bg-white p-[10px] rounded-lg">
<strong>{selectedMarker.title}</strong>
<div className="flex flex-row gap-5 justify-center items-center">
<Image
src="/images/leader_github_logo.png" // public 폴더 안의 이미지 경로
alt="Example Image"
width={100} // 이미지 너비
height={100} // 이미지 높이
/>
<p className="max-w-[350px]">
여기에는 마커에 대한 추가 정보가 들어갑니다.
</p>
</div>
<WeatherInfo lat={list.mapY} lon={list.mapX}/>
<div
className="absolute top-1 right-2 cursor-pointer"
onClick={() => setSelectedMarker(null)}
>
닫기
</div>
</div>
</CustomOverlayMap>
);
}
})
요약
- 카카오맵 SDK 로드 상태를 체크하고 기본 좌표 설정으로 안전성을 강화.
- selectedMarker를 고유 값으로 비교하여 마커 클릭 시 정확한 오버레이 표시.
'본 캠프' 카테고리의 다른 글
리액트 심화 프로젝트 (4) (0) | 2024.12.26 |
---|---|
리액트 심화 프로젝트 (3) (0) | 2024.12.24 |
리액트 심화 프로젝트 (1) (3) | 2024.12.20 |
리액트 주특기 플러스. (9) (1) | 2024.12.19 |
리액트 주특기 플러스. (8) (1) | 2024.12.18 |