codekata 알고리즘 풀이

오늘 알고리즘을 풀다가 아직도 js 배열의 기본 메소드들과 에로우 형식의 함수를 이해하지 못하고 있다는것을 깨달았다. 내가 지금 모르는게 무엇인지 파악하고 완전히 내 것으로 만드는 것이 공부의 목적이니 한번 더 정리해 보도록 한다.

Arrow Function

ECMAScript (or ES) is a scripting-language specification standardized by Ecma International) 은 자바 스크립트를 표준화, 규격화하기위해 만들어진 것으로 2015 년에 나온 ES6 버전이 가장 많이 쓰이고 있다.

ES6에 생긴 대표적인 새로운 문법이 바로 arrow function이다.

기존 ES5 함수에서 이름이 없는 함수는
function(){}로 표현되었다.
하지만 arrow function 은 간단히 다음과 같이 표현한다.
() = >{}
함수의 이름이 있는 경우는 다음과 같다.
ES5
function getName(){}

ES6
const getName=()=>{}

자바 스크립트에서 함수는 (ES5도 마찬가지) 값을 변수에 저장할 수 있다.(자바를 조금 배웠던 나에게는 아주 헷갈리는 부분이고, 써야 유용하지만 절대 안 써지는 부분이 바로 이 부분 !)

ES5

functon getName(){}
const getName = function(){}
const getName = function(name){}

ES6
const getName = (name)=>{}
const getName = name =>{} // 인자가 하나일떄는 소괄호 생략이 가능
const getName =(name,age) = >{} // 인자가 두 개일 때는 생략할 수 없음

ES5
function getName(name){
return name;를 호출한
}

ES6
const hi = name => {return name};
const hi = name = > name;

위와 같이 만약 함수가 실행내용 없이 return 만 한다면 return 키워드와 중괄호가 생략이 가능

Array.map() 함수

배열내의 각각의 모든 요소들에 대해서 주어진 함수를 호출한 결과를 모아서 반환한다.

const array = [1,2,3,4];
const map = array.map(x=>x*2);
console.log(map)
//[2,4,6,8]

Array.forEach() 함수

주어진 함수를 배열 요소에 각각 실행한다.
map()과 달리 리턴하는 것이 없이 undefined 를 반환한다.
탈출하고 싶다면 return 을 해야한다.

const array1 = ['a', 'b', 'c'];

array1.forEach(n => console.log(n));
//예상 출력값 - 'a','b','c'

Array.filter()

주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열로 반환, 함수 테스트 통과하는 요소가 없다면 빈배열이 된다.

const arr = [1,2,3,4];
function check(num){
return num<3;
}
const filtered = arr.filter(check);

console.log(filtered);
//나오는 값 - [1,2]

Array.includes()

배열이 특정 요소를 포함하고 있는지 판별, 반환값은 Boolean 이다.
문자나 문자열을 판별할때는 대소문자를 구분해 주어야한다.

const words = ['aaa','bbb','ccc'];
const check=words.includes('aaa');
console.log(check); // true 가 출력됨
const check2=words.includes('a');
console.log(check2); // false 가 출력
//=> 문자열의 부분으로는 판단할수 없다. 전체 배열들 중에서 내가 지정한 배열값과 동일한것이 있는지만 확인가능

array.indexOf()

베열에서 지정된 요소를 찾을 수 있는 첫번째 인덱스를 반환하고 존재하지 않으면 -1을 반환

예시 1 >

const indexOfArray =['aaa','bbb','ccc'];
console.log(indexOfArray.indexOf('aaa')); // 0이 반환됨

예시 2 - 응용(아래의 알고리즘 문제에 적용하자!)

const indexOfArray1 =['aaa','bbb','ddd'];
const indexOfArray2 = ['ddd','aaa','bbb']

//indexOfArray2의 각 요소들이 indexOfArray1에 순서만 다르게 있을때, indexOfArray2의 각 요소들과 동일한 어레이1 요소들의 인덱스를 찾으려면 ?

indexOfArray2.forEach(n=>console.log(indexOfArray1.indexOf(n))) // 출력 : 2 0 1

//indexOfArray1에서 indexOfArray2의 요소를 가지고 있는 요소를 찾고 , 그 다음 그 요소의 인덱스를 찾아낸다!

Algorithm 문제

twoSum함수에 숫자배열과 '특정 수'를 인자로 넘기면, 더해서 '특정 수'가 나오는 index를 배열에 담아 return해 주세요.

nums: 숫자 배열
target: 두 수를 더해서 나올 수 있는 합계
return: 두 수의 index를 가진 숫자 배열

예를 들어,
nums: 숫자 배열
target: 두 수를 더해서 나올 수 있는 합계
return: 두 수의 index를 가진 숫자 배열

예를 들어,
nums은 [4, 9, 11, 14] target은 13

nums[0] + nums[1] = 4 + 9 = 13 이죠?

그러면 [0, 1]이 return 되어야 합니다.

target으로 보내는 합계의 조합은 배열 전체 중에 2개 밖에 없다고 가정하겠습니다.

이제 필요한 메서드를 모두 정리했으니 문제를 확인하자.

풀이

가장 먼저 떠올릴수있는 방식은 이중반복문을 만들어서 돌리고 각 phase 에서 정답을 충족시키는 배열 요소의 짝을 찾는것이다. 하지만 이렇게 한다면 선택된 배열값의 순서만 다르고 실제 선택된 값은 같은 게 한번더 나오게 되어 이 중 문제에서 요구하는 인덱스의 순서에 맞는 배열값의 쌍을 골라내야한다는 번거로움이 있다.

따라서 이중반복문을 사용하지 않고 다음과 같이 푸는 것이 훨씬더 효율적이다.
아래의 코드는 위코드 22기 (블로그주소 :링크 ) 동기분의 풀이이다.
이를 분석해 보자.

const twoSum = (nums, target) => {
  let result = [];
  const subArr = nums.map(num => target - num);
  
  // 먼저 기존 nums 배열로부터, target에서 각 배열 요소들을 뺀 값들로 만들어진 새로운 배열 subArr 을 만든다. 
  
  const intersection = nums.filter(num => subArr.includes(num));
  
  // filter는 위에서도 언급했듯이 함수의 조건에 맞는 요소들만을 모아 새로운 배열을 만드는 함수이다. 
  // 새로만든 subArr 배열의 요소들중, 기존의 배열 nums 의 요소들을 포함하고 있는것이 있는지 확인한다. 
  //이때의 includes 함수를 만족하는 값(true)가 호출되도록하는 num(nums배열의 요소)가 있다면 이들을 반환하여 새로운 배열 intersection 을 만든다.
  
  intersection.forEach(num => result.push(nums.indexOf(num)))
  
  //intersection의 배열 요소 각각에 result.push(nums.indexOf(num)) 을 적용시킨다.
  // result.push(nums.indexOf(num)) 는 nums 배열의 요소 중 intersection 배열 요소 n 에 해당하는 요소를 찾아내고 그 요소의 인덱스를 처음에 선언한 빈배열 result에 차례대로 push 한다.
  
  return result;
}

좋은 웹페이지 즐겨찾기