- 문자열로 된 배열에서 문자열을 찾는 알고리즘
- indexOf로 접근 가능한 것이 있으면 index 반환, 없으면 -1 반환
- 이걸 어떻게 메서드 사용하지 않고 알고리즘으로 하는지?
목적
- describe what is a searching algorithm is
- implement linear search on arrays
- implement binary search on sorted arrays
- implement a naive string searching algorithm
- implement the KMP string searching algorithm
1. Linear search on arrays
- It is the simplest way
- Search for an value is to look at every element in the array and check if it's the value we want.
JS has search
- indexOf
- includes
- find
- findIndex
How search works? answer: Linear search
Exercise
- This function acceps an array and a value
- Loop through the array and check if the current array element is equal to the value
- if it is, return the index at which the element is found
- if the value is never found, return -1
My try
function linearSearch(array, value) {
for (let i = 0; i < array.length; i++) {
if (i === value) {
return true;
} else return -1;
}
}
잘못한 것
1. array에 해당하는 i를 value와 비교해야하는데, i를 비교하였음
2. 찾았을 시 반환값이 i인데, 반환값을 boolean으로 줘버렸음 (문제를 제대로 읽지 않음)
Solution
function linearSearch(array, value) {
for (let i = 0; i < array.length; i++) {
if (array[i] === value) {
return i;
}
}
return -1;
}
BigO: O(n)
Best: O(1), Average: O(n), Worst: O(n)
2. Binary search on sorted arrays
- Binary search is a much faster form of search
- Rather than eliminating one element at a time, you can eliminate half of the remaining elements at a time
- Binary search on works on sorted arrays!
Divide and Conquer
split up in two pieces, pivot point is in the middle, check left and right, then eliminate, repeat!
Exercise
- This function accepts a sorted array and a value
- Create a left pointer at the start of the array, and a right pointer at the end of array
- While the left pointer comes before the right pointer:
- create a pointer in the middle
- If you find the value you want, return the index
- If the value is too small, move the left pointer up
- If the value is too large, move the right pointer down
- If you never find the value, return -1
My try
function binarySearch(array, value) {
let left = 0;
let right = array.length - 1;
while (left < right) {
let middle = Math.round((array.length - 1) / 2);
if (array[middle] === value) return middle;
else if (array[middle] > value) left++;
else if (array[middle] < value) right--;
}
return -1;
}
잘못된 점
1. middle의 정의, 위치
- middle을 while문 안에 정의하였음. 밖에 정의하여야함
- middle을 (array.length-1)/2로 정의하였는데, 이러면 left가 상승될 때 실제 middle을 찾아주지 못함. 따라서 left의 이동을 고려한 아래와 같이 정의 필요
Math.floor((start+end)/2)
*Math.floor하던 Math.ceil을 하던, 일정하게만 적용해주면 상관 없음
2. while문의 조건, break point 만들어 주기
left<right만 해주었는데, 이건 break point의 조건이고(이도 left<=end로 바꿔야함),
조건문을 array[middle] === value 일때, !== value일때 2가지를 큰 조건으로 걸어주어야함
value가 아닐 때에는 break point가 생길 수 있도록(없으면 infinite loop를 돌게됨) 둘을 포함하는 && 걸어줌
while(array[middle] !== value && start <=end){
}
if(array[middle]===value){
}
Solution
function binarySearch(array, value){
let start = 0;
let end = array.length-1;
let middle = Math.floor((start + end)/2)
console.log(start, middle, end);
while(array[middle] !== value && start <= end){
if(value < array[middle]){
end = middle -1;
} else{
start = middle +1;
}
middle = Math.floor((start + end)/2);
}
if(array[middle]===value){
return middle;
}
return -1;
}
Shortened: if 대신 삼항연산자 사용
function binarySearch(array, value){
let start = 0;
let end = array.length-1;
let middle = Math.floor((start + end)/2)
console.log(start, middle, end);
while(array[middle] !== value && start <= end){
if(value < array[middle])end = middle -1;
else start = middle +1;
middle = Math.floor((start + end)/2);
}
return array[middle] === value ? middle: -1;
}
Big O
Worst/average: O(log n) , Best: O(1)
3. Naive String search
Count the number of times a smaller string appears in a longer string
A straightforward approach involves checking pairs of characters individually
- Long string: wowomgzomg
- Short string: omg
- 2 matches
Pseudocode
- function that takes two string, longer string, shorter string
- loop over the longer string
- nested loop: loop over the shorter string
- if the characters don't match, break out of the inner loop
- if the characters do match, keep going
- if you complete the inner loop and find a match, increment the count of matches
- return the count
Try
function navieSearch(long, short) {
let count = 0;
for (let i = 0; i < long.length; i++) {
for (let j = 0; j < short.length; j++) {
if (i !== j) {
return;
//break out of the inner loop
} else {
return;
//keep going
}
}
}
count++;
return count;
//increment the count of matches
}
잘못된 점
1. 배열에서 index (i)와 i의 value에 대한 착각
i의 value와 비교해야하는데 i(index)자체를 비교함
*위에도 했던 실수
2. break문을 몰랐음
break 문은 현재 반복문, switch문, 또는 label문을 종료하고, 그 다음 문으로 프로그램 제어를 넘깁니다.
3. 비교방법
4. match가 될 때 어떻게 확인할지에 대한 고민이 없었음
if you complete the inner loop and find a match, increment the count of matches
이 부분에서 끝까지 같은게 맞는지 어떻게 확인하는지에 대한 고민이 없었음
Solution
function navieSearch(long, short) {
let count = 0;
for (let i = 0; i < long.length; i++) {
for (let j = 0; j < short.length; j++) {
//console.log(long[i],short[j],long[i+j])
if (short[j] !== long[i + j]) {
//console.log("BREAK!")
break;
}
if (j === short.length - 1) {
//마지막까지 갔을 때
//console.log("FOUND ONE")
count++;
}
}
}
return count;
}
navieSearch("wowomgzomg", "omg");
'알고리즘' 카테고리의 다른 글
[Elementary Sorting Algotithms] Selection sort (0) | 2022.12.18 |
---|---|
[Elementary Sorting Algotithms] Bubble sort (0) | 2022.11.20 |
[재귀] someRecursive (0) | 2022.10.31 |
재귀: recursive range, Fib (0) | 2022.10.02 |
재귀: power 제곱, factorial 계승 (0) | 2022.09.03 |