Front-End

프로그래머스 기초트레이닝 시작 본문

알고리즘

프로그래머스 기초트레이닝 시작

jeongsso 2023. 8. 4. 23:40

알고리즘을 왜 배우고 공부하는가? 에 대해 생각해 보자.

어떤 식의 코드를 사용해야 원하는 방법을 도출할 수 있는지 확인하기 위해 자료 구조를 파악하면서

생각하는 기술

 

흔히 삽질을 많이 해야 실력이 늘 것이다 하는 것이

어떤 식으로 할지의 상상의 나래를 펼쳐서 시도해 보는 것이라고 생각하면 될 것 같다 ㅎㅎ!!

(저의 선생님들께서 하시던 말씀 ㅎㅎ'상상의 나래를 펼쳐라', '삽질이 실력으로 된다'였습니다)

 

 

알고리즘을 보게 되면 문제를 먼저 파악하고 어떤 순서로 풀어나가야 할지 생각해야 합니다.

처음엔 어떤 말인지 이해하기 어려울 수 있지만,

문제와 예시를 보면서 도출해야 하는 것도 공부라고 생각됩니다!!

 

 

8/4 알고리즘 기초 4문제를 풀었습니다.
(풀고 나서 다시 복기하는 것이 좋을 것 같기에 하루 텀으로 블로그와 문제풀이를 진행하였습니다!)

 

 


 

문제 1.  카운트 업


문제 설명

정수 start와 end가 주어질 때, start부터 end까지의 숫자를 차례로 담은 리스트를 return 하도록 solution 함수를 완성해 주세요.

 

 

입출력 예

start end result
3 10 [3,4,5,6,7,8,9,10]

 

 

입출력 예 설명

3부터 10까지의 숫자들을 담은 리스트 [3, 4, 5, 6, 7, 8, 9, 10]를 return 합니다.

 

 

저의 풀이!

function solution(start, end) {
var answer = [];
for (let i = start; i <= end; i++) {
// 만약 곱하기하거나 하면 i 부분에 설정하면됨
answer.push(i);
}
return answer;
}

console.log(solution(3, 10));

 

 

메모

for문에서 괄호 안을 설명하자면
for ( i 변수를 선언하고; 조건문을 넣고; i를 늘어나게 할지? 줄어들게 할지? 설정하는 스텟 부분) {

         어떤 식으로 내보낼 것인지! 적어두는 곳이라고 간단하게 생각하면 될 것 같습니다.

    }

 

for 문에 대해서 좀 더 자세히 파해치면 좋을 것 같다.

=> for문에는 종류가 6가지 정도나 있다.

1. for

가장 기본적인 

for (let i = 0; i < 10; i++) {
    console.log(i);
}

for문 안의 구성이 각각 의미하는 바를 살펴보면,

let i =0;  👉 변수 let i를 선언하고 0으로 할당 ( 반복문의 초기값을 설정하는 것이다)

i < 10;     👉 for 문을 얼마나 돌릴 것 인지? 조건을 설정 ( 조건이 참이면 실행하는 )

i++.         👉  루프가 돌 때마다 변수 증감식 

 

풀어서 해석하면 i는 0부터 시작해서 10보다 작을 때까지 즉, 0~9까지 총 10번 반복할 것이며,

i의 값은 한번 돌때마다 1씩 증가하여 출력될 것이라는 겁니다!

 

2. for ...in

for in은 object에 사용할 수 있는 반복문이다. ( 배열에서도 사용할 수 있지만 추천하지는 X )

const obj = {
    name: '이름',
    age: '나이',
};

for (const key in obj) {
    console.log(key); // key값 출력
    console.log(obj.name, obj.age); // value 값 출력

    console.log(`key 값 : ${key}`); // 1. key값 : 이름 // 2. key값 :age
    console.log(`value 값 : ${obj[key]}`); // 1. value 값 : 이름 // 2. value값 : 나이
}

생김새는 for문과 비슷해보이지만 for 옆에 in 키워드를 사용합니다.

obj.name과 같이 사용하려면 object내에 name 이라는 key값을 가진 value가 존재해야하고

없는 key값을 사용하면 undefined가 출력됩니다.

 

객체의 모든 value값을 얻으려면 obj[key]로 객체를 순회하여 얻을 수 있습니다.

 

제가 편하게 보기위해 요약한 부분입니다! (제 생각은 참고만 해주십셔)

object 의 key - value 값이 있다면 그 key와 value를 모두 순서대로 출력해 줄 수 있다.

굳이 내가 하나씩 찝어서 obj의 key의 value를 출력해줘라 하지않아도 된다는 것 같다.

 

3. for ...of

for of 문은 반복 가능한 객체(Array, Map, Set, String, TypedArray, arguments 객체 등)에 대해 

사용할 수 있습니다.

 

보통은~~ Array 배열에 많이 사용한다고 합니다!

const array = ['1번', '2번', '3번'];

for (const element of array) {
    console.log(element); // 배열[0] ~ 끝까지 순차적 출력
    // 위에거는 출력되는 걸 보면 
         1번
         2번
         3번
          이렇게~ 출력이되고
 
    console.log(array); // 배열 전체 출력
    // 이거는 
      ['1번', '2번', '3번']  이대로 출력이 됩니다요
 
}

배열에 들어오는 0번째 인덱스 부터 마지막번째 인덱스까지 순차적으로 출력됩니다.

 

4. forEach()

배열에 사용되는 메서드입니다.

인자에는 콜백함수를 넣어서 사용해야한다.

const array = ['1번', '2번', '3번'];

array.forEach(element => {
    console.log(element);
});

코드만 봐서는 이해하기 어려울 수 있다.

간단하게 보면~

배열명.forEach(요소명 =>{
    실행문(요소명)
})

요소명은 내가 정할 수 있고, 그 배열이 가지고 있는 요소들을 한 번씩 반환하여 반복을 시켜주는 것이다.

 

5. while()

조건이 참일 경우에 실행되는 반복문이다.

while (condition) {
// condition이 참이면 실행
}

보기에는 그냥 if문이랑 크게 다름이 없어보인다만, 얘는~ 반복을 시켜준다는점!

while문 옆 인자( condition )이 참이 아닌 거짓인 경우 단한번도 실행해주지않는다.

 

원래는 조건이 false(거짓)이 되면 알아서 빠져나오는데,

특별한 지시자인 break를 사용하면 언제든 반복문을 빠져나올 수 있다.

let sum = 0;

while (true) {
let value = +prompt('숫자를 입력하세요.', '');

if (!value) break; // (*)

sum += value;
}
alert('합계: ' + sum);

이런 식으로 if로 조건을 걸어서 break를 써주게되면 그 이후로 반복문이 멈추게된다.

 

break 같은 경우는 '이거라면 ! 여기부터 멈춰!! '하면서 즉시 중단이 되는것이고

 

뭐 ' 이럴경우 얘는 뛰어넘고 다음 반복문부터 진행해줘~' 라고 하고 싶을 때도 있을텐데 이럴 때는

countinue라는 걸로 사용합니다

쉽게 생각하면 break의 가벼운 버전이라 생각하면됩니다.

(break는 전체 반복문 멈춤 / countinue는 실행중인것만 멈추고 다음부터 재실행~)

for (let i = 0; i < 10; i++) {
// 조건이 참이라면 남아있는 본문은 실행되지 않습니다.
if (i % 2 == 0) continue;
    alert(i); // 1, 3, 5, 7, 9가 차례대로 출력됨
}

 

여기서 말한 break / countinue 는 for문, do...while문에서도 사용할 수 있는 지시어다.

 

6. do...while()

위에 while과 달리 do{}에 작성된 코드는 최소 1번은 꼭 실행되는거고

최소 1번 실행 후, while조건이 false인 경우 더이상 실행되지 않는다.

do {
// 거짓이더라도
//do에 작성된 코드는 무조건 1회는 실행
} while (condition);

적어도 1번! 실행하고 싶을 때 사용하는 코드다.

 

 


 

 

 

문제 2.  카운트 다운


문제 설명

정수 start와 end가 주어질 때, start에서 end까지 1씩 감소하는 수들을 차례로 담은 리스트를 return 하도록 

solution 함수를 완성해 주세요.

 

 

입출력 예

start end result
10 3 [10,9,8,7,6,5,4,3]

 

 

입출력 예 설명

10부터 3까지 1씩 감소하는 수를 담은 리스트는 [10, 9, 8, 7, 6, 5, 4, 3]입니다.

 

 

저의 풀이!

function solution(start, end) {
var answer = [];

for (let i = start; i >= end; i--) {
answer.push(i);
}

return answer;
}

console.log(solution(10, 3));

 

 

 

메모

위의 풀이와 비슷하지만 i를 감소시켜 주는 점이 다릅니다!! i++ => i-- 로 ㅎㅎ

 

 

 

 

 


 

 

 

문제 3.  공배수


문제 설명

정수 number와 n, m이 주어집니다. number가 n의 배수이면서 m의 배수이면 1을 아니라면 0을 return 하도록

solution 함수를 완성해 주세요.

 

 

입출력 예

number n m result
60 2 3 1
55 10 5 0

 

 

입출력 예 설명

60은 2의 배수이면서 3의 배수이기 때문에 1을 return 합니다.

 

55는 5의 배수이지만 10의 배수가 아니기 때문에 0을 return 합니다.

 

 

저의 풀이!

function solution(number, n, m) {
var answer = 0;

if (number % n === 0 && number % m === 0) {
       answer = 1;
    } else {
       answer = 0;
    }
    return answer;
  }

console.log(solution(55, 10, 5));

// 삼항으로 변경해보면 ->
// return 되는 부분에서 조건문을 넣고싶을때 써야한다.
// 변수도 굳이 지정하지않아도 답을 추출해낼수 있다.
function solution2(number, n, m) {
     return number % n === 0 && number % m === 0 ? 1 : 0;
  } 

console.log(solution2(55, 10, 5));

 

 

메모

if 문에서 꼭 return을 붙이지 않아도 된다.
짧으면 굳이 가독성도 좋기 때문에 안 붙여도 되지만, return 문이 길다면 가독성을 위해 써도 좋다.

 

삼항연산자를 사용할 때는 return문안에 조건문을 넣고 싶을 때 사용해야 한다. if문은 return문 안쪽에다가는 넣지 못하기 때문이다. 변수도 따로 지정하지 않아도 답을 추출해 낼 수 있다.

 

 

 

 


 

 

 

문제 4.  이어 붙인 수


문제 설명

정수가 담긴 리스트 num_list가 주어집니다. num_list의 홀수만 순서대로 이어 붙인 수와 짝수만 순서대로 이어 붙인 수의 합을 

return 하도록 solution 함수를 완성해 주세요.

 

입출력 예

num_list result
[3,4,5,2,1] 393
[5,7,8,3] 581

 

 

입출력 예 설명

홀수만 이어 붙인 수는 351이고 짝수만 이어 붙인 수는 42입니다. 두 수의 합은 393입니다.

 

홀수만 이어 붙인 수는 573이고 짝수만 이어 붙인 수는 8입니다. 두 수의 합은 581입니다.

 

 

저의 풀이!

function solution(num_list) {
let 홀수 = "";
let 짝수 = "";

for (let i = 0; i < num_list.length; i++) {
   if (num_list[i] % 2 === 1) {
        홀수 += num_list[i];
     } else {
        짝수 += num_list[i];
     }
  }
  return +홀수 + +짝수;
// 또는
   return Number(홀수) + Number(짝수); 도 가능합니다
}

console.log(solution([3, 4, 5, 2, 1]));

 

 

메모

일단 문제자체가 생각하는데 좀 오래 걸렸다.

간단하게 말하자면 홀수는 홀수끼리 짝수는 짝수끼리 string으로 붙여서 쓰고,

마지막에 붙여서 만들어진 수를 string이 아닌 number로 덧샘을 해줘라 라는 의미였습니다.

 

일단 홀수-짝수를 분리해서 string으로 변환 후 덧샘을 하고,
string인 결과를 number로 변환해서 덧샘을 해주면 되는 문제였습니다.

여기서 제가 새롭게 안거는 +홀수처럼 자바스크립트는 숫자가 아닌 타입에 숫자연산자를 쓰게 되면 

자동으로 '잘 못썼나 보네~ ' 하고 변환을 시켜줘 버립니다. 

 

이를 자바스크립트 형변환이라고 합니다 

=> 형변환이란 "함수와 연산자에 전달되는 값은 대부분 적절한 자료형으로 자동 변환되는 것" 입니다. 

      전달받은 값의 자료형과 관계없이 이를 문자열로 자동 변환하여 보여주는 것이나,

      수학 관련 연산자가 전달받은 값을 숫자로 변환하는 경우가 형 변환의 대표적인 예시입니다.

 

      자, 예를 들어서~ 

      alert 메서드는 매개변수로 문자형을 받기 때문에, alert(value)에서 value는 문자형이어야 합니다.

      만약~ 여기서 다른형태의 값을 전달 받으면 이 값은 문자형으로 자동 변환이됩니다.

let value = true;
alert(typeof value); // boolean

value = String(value); // 변수 value엔 문자열 "true"가 저장됩니다.
alert(typeof value); // string

         만약 typeof를 쓰지않고 value만 했다면? 당연히~ "true"로 나왔을겁니다.

 

         숫자형으로 변환되는 경우는 연산자를 쓸경우 그렇게 되는데,

          +인 경우는 텍스트여도 이어쓰기로 되지만 나누기(/)나 문자열앞에 + or - 를 붙여서 쓸경우 숫자로 자동 변환됩니다.

alert( "6" / "2" ); // 3, 문자열이 숫자형으로 자동변환된 후 연산이 수행됩니다.

         true 인경우에는 숫자로는 1이 반환되고, false인 경우에는 숫자로 0이 반환됩니다.

         또 null 일경우도 0이 반환되지만!!

         undefined일 경우에는 NaN이 반환됩니다.

 

 

 

 

그리고 홀수 짝수의 변수를 선언할 때는 var, let 으로 선언해야 전체 호출이 가능하고 

const로 할 경우 블록함수..였나 확실하게 기억이 안 나서 이 부분도 다시! 공부하고 자세히 설명해 두도록 하겠습니다.

 

여기서 한번 반성.... 이미 다 공부한건데.. 이렇게 사람이 안하다보면 까먹고 .. 무지합니다...

 

https://gldi1633.tistory.com/34

 

let, const 키워드와 블록 레벨 스코프

드디어 let cont var 차이를 공부할 때가 왔다 드가자 = 1. var 키워드로 선언한 변수의 문제점 = ES5까지 변수를 선언할 수 있는 유일한 방법은 var 키워드를 사용하는 것이었다. var 키워드로 선언된 변

gldi1633.tistory.com

여기서도 보면 이미 열심히 공부하고 정리해두었지만, 

작년 12월에 적어둔거라고 기억이 희미한게 안타까운 상황이니 다시한번 복습하도록 하겠습니다.

 

 

 

var 

중복 선언이 가능합니다.

오로지 함수 블록만을 지역스코프로 인정해서 코드 블록인(if, for, while등)은 무시하고 전역변수로 쳐버립니다.

호이스팅이 선언 단계와 초기화 단계가 한번에 진행되어서 변수를 선언한게 호출한것보다 나중이어도 위로 끌어와서 이미 선언된 것 처럼 작동합니다.

할당하는 부분에 도달해야 할당되서 할당 이후에 값이 undefined에서 지정한 값으로 변환되어 추출됩니다.

전역객체의 프로퍼티가 가능해서 window.x로 호출할 수 있다.

 

 

let 

중복 선언 불가넝!! 하지만 재할당은 가넝~(같은 스코프내에서 재할당하면 중복선언으로 판단하고 에러가 뜰것이다)

let nationality = 'KR' ; // let 변수 선언
let nationality = 'US' ; // 재선언 -> 에러 : SyntaxError: Identifier 'nationality' has already been declared

let lastname = 'Oh'; //let 변수 선언
lastname = 'Kim' ;// 재할당 가능

얘는 함수, if문, for문 코드블록을 지역스코프로 인정하는 블록레벨 스코프입니다.

호이스팅에서 var와 다르게 '선언' 과 '초기화'가 따로 분리되어 진행되서 선언은 런타임 이전에 되지만,

초기화와 할당은 변수선언을 하는 즉시에 초기화와 할당이 이루어집니다.

그것 때문에 스코프 시작점부터 초기화 시작지점까지 변수를 참조할 수 없는 구간이 있는데, 여기를 TDZ일시적 사각지대라고 함니당

그리고 아무리 전역객체도 된다해도 얘는 window.x로 호출할 수 없다

 

const 

중복선언, 재할당 불가능!

얘도 블록선언 스코프를 가지고있다 (let과 동일)

const로 선언한 변수는 반드시 선언과 동시에 초기화를 해야한다.( let은 선언하고~ 나중에 초기화 할당을해도되는데 const는 안됨)

그래서 변수 호이스팅이 발생하지 않는것처럼 보일 수 있다.

 

 

 

스코프에서도 헷갈리면 참고하면 좋을듯하다! 😉

https://gldi1633.tistory.com/32

 

스코프란 뭔가

스코프가 뭔가유 ? 스코프 = 유효범위 스코프는 변수 그리고 함수와 깊은 관련이 있다. function add(x, y) { // 매개변수는 함수 몸체 내부에서만 참조할 수 있다. // 즉, 매개변수의 스코프(유효범위)

gldi1633.tistory.com

 

 

 

 

Comments