[220105] for문, 이중for문(구구단, 별짓기), 재귀함수, 다이나믹 프로그래밍(피보나치, 메모이제이션)
목차
1. for문
2. 이중for문
3. 구구단만들기
4. 별짓기
5. 재귀함수
for ( 초기문; 조건문; 증강문)
for문의 목표 : 내가 같은 코드를 몇번을 반복시킬 것인가
for(let i=1; i<11; i++) {
if(i==5) {
console.log('hello world');
}
else {
console.log(i)
}
}
for문과 if문을 응용한 코드. 1부터 10까지 출력하면서 5가 출력될때는 hello, world를 출력한다.
for문 응용
<script>
function print() {
// 1-10가지 출력, 5일때 hw로 바꿔서 출력
for(let i=1; i<11; i++){
if(i==5){
console.log("hello world!\n");
}
else {
console.log(i);
}
}
}
print();
</script>
첫 시도할때 무한정으로 돌아가면서 창이 멈추길래 ??? 하고 있었는데, if문에서 i=5라고 적은거 발견. 프로그래밍에서는 i==5다 기억해.
식을 짜는 것보다 function 함수를 만들어서 바깥으로 꺼내는게 더 어려웠다. 익숙해지자.
이중for문
for문 안에 for문을 들어가는 행위. 코테 상위 문제가 3중 for문이고 대중적으로는 2중 for문으로 다 때려박아서 해치울 수 있다.
for(let i=0; i<10; i++){
for(let j=0; j<10; j++){
console.log("값은",i,j);
}
}
대표적인 예제문제 : 구구단 만들기
- 앞자리 수, 뒷자리수 모두 지정
function guguclass(num){
for(let i=1; i<10; i++){
console.log(num+"*"+i+"="+num*i);
}
}
guguclass(3);
- for문의 특성 기억 : 끝날때까지 for문은 멈추지않는다. 코드가 실행이 끝나야 for문 블럭을 벗어남.
function guguclass(){
for(let i=2; i<10; i++){
for(let j=1; j<10; j++){
console.log(i+'*'+j+'='+i*j);
}
}
}
guguclass();
대표적인 예제문제 : 별짓기
- 별 완성이 목적이 아님. 위 for문과 아래for문의 역할을 구별하기 위한 역할
for(let i=4; i>0; i--){
let str1=""; // 빈 문자열 생성
for(let j=4; (j-i)>0; j--){ str1+=' '; }
for(let k=0; k<(i*2)-1; k++){ str1+="#"; }
console.log(str1)
}
for문 이해도를 높이기 너무 좋은 문제였다. (= 해결할 수 있는 화딱지를 내기 너무 좋은 문제였다.)
어설프게 알고 있던건 알았는데 어디를 모르는건지 몰랐는데 알게 되었다.
for(let i=4; i>0; i--){}
4
3
2
1
이렇게 줄어든다.
for(let i=4; i>0; i--){
for(let j=4; j>0; j--){ }
}
4 / 4,3,2,1
3 / 3,2,1
2 / 2,1
1 / 1
이렇게 될거라고 생각했는데 그게 아님.
4 / 4,3,2,1
3 / 4,3,2,1
2 / 4,3,2,1
1 / 4,3,2,1
이렇게 됨.
- 감소연산자인 --는 수를 감소시키는 것은 맞다.
- let j=4; j>0; j-- 이 상태에서 j를 감소시켜 4,3,2,1로 만드는 것도 맞다
- 하지만 처음 for문이 선언될때(반복되서 돌아왔던 처음이던) let j=4라고 선언을 했다. 거기서 1씩 감소해나가는거지, j 초기값을 바꾸는 것은 아님!! 0부터 시작하고 싶으면 let j=0이라고 해야함!
재귀함수 : 자신 안에 자기 자신을 또 불러오는 함수.
스택구조인데, 실행되기전까지 다 쌓아놓고, 다 끝나면 맨 위부터 끄집어내며 실행한다.
function ingoo(n){
if(n<=1) {
return 1 //예외지정
}
return n + ingoo(n-1)//자기자신을 호출
}
console.log(ingoo(100))
스택구조를 모르겠다면 게시글 참조 : https://hancoco.tistory.com/74
좀더 쉽게 보는 재귀함수
function ingoo(n){
if(n<=1) {
return 1 //예외지정
}
let answer=ingoo(n-1)
//실행이 다 되기전까지는 여길 못 벗어남 안녕도르마무
//죄다 콜 스택에 쌓임
//다 쌓이는 순간 이제 할게 없으니까 밑 코드가 실행
console.log(answer)
return n + answer//자기자신을 호출
}
1 | |||||
97 | 2 | 2 | |||
98 | 98 | ... | ... | ||
99 | 99 | 99 | 99 | 99 | |
100 | 100 | 100 | 100 | 100 | 100 |
코드를 실행할때 걸리는 시간
시작 : console.time()
끝 : console.timeEnd()
1-100가지 더하시오
- for문 : 0.18 - 단점 : 오래걸림
- 수학공식 : 0.02 - 단점 : 공식을 알아야함
- 재귀함수 : 0.04 - 이유 : 한가지 일만 하는 스택을 사용하기 때문
걸리는 시간의 차이. 그냥 효율은 좋구나-만 알면 좋음ㅇㅇ 지금 수준에서 그거 따져봤자 노의미.
현업에서도 다른 일이 더 바쁘지 작은일 담당 업무 아니면 최적화 할 시간 없음.
자바스크립트 : 진짜 배열을 쓰는게 아니라 배열처럼 보이는 객체를 사용하고있어서 어 좀 그래여.
그 증거가 typeof를 하면 배열이 object가 뜨는거. 그리고 배열은 느려여.
스택오버플로우
허용능력을 넘어가면 에러를 띄움
다이나믹 프로그래밍 난이도 상
그래프+DP 카카오 네이버 배민 프로그래밍적인 사고능력
가장 첫번째 순서가 피보나치 수열
1, 1, 2, 3, 5, 8, 13, 21, 34, 55...
function fibo(n){
if(n==1 || n==2){
return 1
}
return fibo(n-1)+fibo(n-2)
}
이대로하면 같은 계산을 계속 반복하므로 속도가 상당히 느리다. 50번이라도하면 튕김.
계산 횟수를 줄이는 메모이제이션
한번 계산한것은 저장했다가 필요할때 꺼내씀 -> 원리는 리액트때 알 수 있음.
메모이제이션에 관해 올린 실사용 코드 글 : https://hancoco.tistory.com/29
계산이 반절이 날아감. n*2 -> n이 되는 방법