Web Dev/2. JS 알고리즘
[자바스크립트로하는 자료구조와 알고리즘] 1- 5장
hYhY1234
2021. 5. 14. 16:19
728x90
책이 매우 좋다. 자바스크립트로 이래저래 삽질하고 해왔던 사람이라면 이책으로 내용을 다 한번 정리하면 효과가 좋을 것 같다.
// O(n)
function exampleLinear(n){
for(let i = 0; i < n; i++){
console.log(i);
}
}
// O(n*n)
function exampleLinear2(n){
for(let i = 0; i < n; i++){
for(let j = 0; j < n; j++){
console.log(j);
}
}
}
// O(n*n*n)
function exampleLinear3(n){
for(let i = 0; i < n; i++){
for(let j = 0; j < n; j++){
for(let k = 0; k < n; k++){
console.log(k);
}
}
}
}
// O(logN)
function exampleLagartithmic(n){
for(let i = 2; i <=n; i = i*2){
console.log(i);
}
}
// isEquivalent(a, b)
function isEquivalent(a, b){
let aProps = Object.getOwnPropertyNames(a); // 프로퍼티만 뽑는다
let bProps = Object.getOwnPropertyNames(b);
if(aProps.length != bProps.length){
return false;
}
for(let i = 0; i < aProps.length; i++){
let propName = aProps[i];
if(a[propName] !== b[propName]){
return false;
}
}
return true;
}
isEquivalent({'hi': 12}, {'hi': 12}); //
console.log({'hi': 12} == {'hi': 12},{'hi': 12} === {'hi': 12}) // 메모리 주소를 비교해서 다르다고 나온다.
// 부호, 지수, 가수
// https://codetorial.net/articles/floating_point.html
// 이진수 소수점으로: https://coming1007.tistory.com/205
function numberEquals(x, y){
return Math.abs(x-y) < Number.EPSILON; // 두개의 표현가능한 숫자 사이의 최소 차이
}
numberEquals(0.1 + 0.2, 0.3)
// 숫자 알고리즘
function isPrime(n){
if(n <= 1) return false;
if(n <= 3) return true;
if(n % 2 == 0 || n % 3 == 0) return false;
for(let i = 5; i * i <= n; i += 6){
if(n % i == 0 || n % (i+2) == 0){
return false;
}
}
return true;
}
function primeFactors(n){
while(n%2 == 0){
console.log(2);
n = n / 2;
}
for(let i = 3; i*i <= n; i+=2){
while(n%i==0){
console.log(i);
n = n/i;
}
}
if(n > 2){
// 소수인 경우
console.log(n);
}
}
primeFactors(200);
function example1(base, exponent, modulus){
return Math.pow(base, exponent) % modulus;
}
function example1_2(base, exponent, modulus){
if(modulus === 1) return 0;
let value = 1;
for(let i = 0; i < exponent; i++){
value = (value * base) % modulus;
}
return value;
}
function isPrime3(n){
for(let i = 0; i <= n; i++){
if(isPrime(i)){
console.log(i);
}
}
}
isPrime3(100);
function maxDivide(number, divisor){
while(number % divisor === 0){
number /= divisor;
}
return number;
}
function isUgly(number){
number = maxDivide(number, 2);
number = maxDivide(number, 3);
number = maxDivide(number, 5);
return number === 1;
}
function arrayN(n){
let counter = 0, currentNumber = 1, uglyNums = [];
while(counter !== n){
if(isUgly(currentNumber)){
counter++;
uglyNums.push(currentNumber);
}
currentNumber++;
}
return uglyNums;
}
arrayN(11);
'dog'.charAt(1)
'youtube'.substring(1, 2);
'youtube'.substring(3, 7);
console.log('a' < 'b') // 사전순
console.log('add' < 'b')
'Red Dragon'.indexOf('Red');
'Red Dragon'.indexOf('Blue');
function existsInString(stringValue, search){
return stringValue.indexOf(search) !== -1;
}
console.log(existsInString('red', 'r'));
console.log(existsInString('red', 'b'));
// 문자가 몇개 등장하는지 확인
let str = "He's my king from this day until his last day";
let count = 0;
let pos = str.indexOf('a');
while(pos!== -1){
count++;
pos = str.indexOf('a', pos+1);
}
console.log(count);
'Red Dragon'.startsWith('Red');
'Red Dragon'.endsWith('Dragon');
'Red Dragon'.startsWith('Dragon');
'Red Dragon'.endsWith('Red');
let test1 = 'chicken,noodle,soup,broth';
test1.split(",")
test1.split("")
"Wizard of Oz".replace("Wizard", "witch");
"Apples hello apples and orange and strawberry".replace(/apples/gi, "hello")
let str1 = "JavaScript DataStructures";
let n = str1.search(/DataStructures/);
console.log(n);
function regexTest(){
let reg = /\d+/;
console.log(reg.test("123"));
let reg2 = /^\d+$/;
console.log(reg2.test("123a"));
let reg3 = /^[0-9]*.[0-9]*[1-9]*$/ // let reg3 = /^[0-9]*.[0-9]*[1-9]+$/
console.log("12", reg3.test("12"));
console.log("1", reg3.test("1"));
}
regexTest();
let dictionary = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".split('');
function encodeId(num){
let base = dictionary.length;
let encoded = '';
if(num === 0) return dictionary[0];
while(num > 0){
console.log('num', num, base, num % base, Math.floor(num / base))
encoded += dictionary[(num % base)];
num = Math.floor(num / base);
}
console.log("encoded", encoded);
return reverseWord(encoded);
}
function reverseWord(str){
let reversed = "";
for(let i = str.length - 1; i >= 0; i--){
reversed += str.charAt(i);
}
// 앞에있을수록 나중에 더해진 것임(reverse해서)
return reversed;
}
function decodeId(id){
let base = dictionary.length;
let decoded = 0; // 마지막 몫
for(let index = 0; index < id.split("").length; index++){
decoded = decoded * base + dictionary.indexOf(id.charAt(index)); // 그다음 몫 + 나머지
}
return decoded;
}
console.log(encodeId(11231230));
console.log(decodeId('VhU2'))
// 자바스크립트의 배열
const arr = [1,2,3,4,5];
findSum(arr, 9);
function findSum(arr, weight){
for(let i = 0; i < arr.length - 1; i++){
for(let j = i; j < arr.length; j++){
if(arr[i] + arr[j] === weight){
return [i, j] // [arr[i], arr[j]]; // 인덱스 반환
}
}
}
return -1;
}
function findSumBetter(arr, weight){
const hashtable = {};
for(let i = 0; i < arr.length; i++){
let currentElem = arr[i];
let diff = weight - currentElem; // arr[i] 가 5라면 차이가 4인 경우에는 5가 뽑혔던 것?
console.log(currentElem, diff, hashtable);
if(hashtable[currentElem] !== undefined){ // 차이 5를 만들었던 인덱스가 있는지(4가 차이 5를 만든다)
return [i, hashtable[currentElem]];
}else{
// 차이 diff를 인덱스 i가 만든다는 것을 기록
hashtable[diff] = i; // diff가 4일때는 4번째 요소인 5가 뽑혔던 것
}
}
}
console.log(findSumBetter(arr, 9));
// slice 구현
function arraySlice(array, beginIndex, endIndex){
if(!beginIndex && !endIndex){
return array;
}
if(!endIndex){
endIndex = array.length;
}
const partArray = [];
for(let i = beginIndex; i < endIndex; i++){
partArray.push(array[i]);
}
return partArray;
}
arraySlice([1,2,3,4], 1,2);
// median
function medianOfArray(array){
const length = array.length;
if(length % 2 === 1){
return array[Math.floor(length / 2)];
}
return (array[length/2] + array[length/2 - 1]) / 2;
}
function medianOfTwoSortedArray(arr1, arr2, pos){
if(pos <= 0) return -1;
if(pos === 1) return (arr1[0], arr2[0]) / 2;
if(pos === 2) {
return (Math.max(arr1[0], arr2[0]) + Math.min(arr1[1], arr2[1])) / 2
}
let median1 = medianOfArray(arr1);
let median2 = medianOfArray(arr2);
if(median1 === median2){
return median1;
}
let evenOffset = pos % 2 === 0 ? 1 : 0; // 배열 짝수면 1, 홀수면 0
let offsetMinus = Math.floor(pos/2) - evenOffset;
let offsetPlus = pos - Math.floor(pos/2) + evenOffset;
if(median1 < median2) {
return medianOfTwoSortedArray(arr1.slice(offsetMinus), arr2.slice(0, -offsetMinus), offsetPlus);
}else{
return medianOfTwoSortedArray(arr2.slice(offsetMinus), arr1.slice(0, -offsetMinus), offsetPlus);
}
}
medianOfTwoSortedArray([1,2,3], [4,5,6], 3)
medianOfTwoSortedArray([11,23,24], [32,33,450], 3)
medianOfTwoSortedArray([1,2,3], [2,3,5], 3)
function commonElements(kArray){
let hashmap = {};
let last = null;
let answer = [];
for(let i = 0; i < kArray.length; i++){
let currentArray = kArray[i];
last = null;
for(let j = 0; j < currentArray.length; j++){
let currentElement = currentArray[j];
if(last !== currentElement){
if(!hashmap[currentElement]){
hashmap[currentElement] = 1;
}else{
hashmap[currentElement]++;
}
}
last = currentElement;
}
}
for(let prop in hashmap){
if(hashmap[prop] === kArray.length){
answer.push(parseInt(prop));
}
}
return answer;
}
commonElements([[1,2,3], [1,2,3,4], [1,2]]);
let M = [
[1,2,3,4,5],
[6,7,8,9,10],
[11,12,13,14,15],
[16,17,18,19,20]
]
function spiralPrint(M){
let topRow = 0, leftCol = 0, btmRow = M.length - 1, rightCol = M[0].length - 1;
while(topRow < btmRow && leftCol < rightCol){
// 우선 시작하는 열의 column을 다 출력한다.
for(let col = 0; col <= rightCol; col++){
console.log(M[topRow][col]);
}
// 다음행으로
topRow++;
for(let row = topRow; row <= btmRow; row++){
console.log(M[row][rightCol]);
}
rightCol--;
if(topRow <= btmRow){
for(let col = rightCol; col >= 0; col--){
console.log(M[btmRow][col]);
}
btmRow--;
}
if(leftCol <= rightCol){
for(let row = btmRow; row > topRow; row--){
console.log(M[row][leftCol]);
}
leftCol++;
}
}
}
spiralPrint(M);
function checkRow(rowArr, letter){
for(let i = 0; i < 3; i++){
if(rowArr[i] !== letter){
return false;
}
}
return true;
}
function checkColumn(gameBoardMatrix, columnIndex, letter){
for(let i = 0; i < 3; i++){
if(gameBoardMatrix[i][columnIndex] !== letter){
return false;
}
}
return true;
}
function ticTacTowWinner(gameBoardMatrix, letter){
let rowWin = checkRow(gameBoardMatrix[0], letter) || checkRow(gameBoardMatrix[1], letter) || checkRow(gameBoardMatrix[2], letter)
let colWin = checkColumn(gameBoardMatrix, 0, letter) || checkColumn(gameBoardMatrix, 1, letter) || checkColumn(gameBoardMatrix, 2, letter)
let diagonalWinLeftToRight = (gameBoardMatrix[0][0]===letter && gameBoardMatrix[1][1]===letter && gameBoardMatrix[2][2]===letter )
let diagonalWinRightToLeft = (gameBoardMatrix[0][2]===letter && gameBoardMatrix[1][1]===letter && gameBoardMatrix[2][0]===letter )
return rowWin || colWin || diagonalWinLeftToRight || diagonalWinRightToLeft;
}
const board = [
['o', '-', 'x'],
['-', 'o', '-'],
['-', 'x', 'o']
]
ticTacTowWinner(board, 'x');
ticTacTowWinner(board, 'o');