---
title: 【LeetCode】0028. Find the Index of the First Occurrence in a String
date: 2023-02-15
is_modified: false
disqus: cynthiahackmd
categories:
- "面試刷題"
tags:
- "LeetCode"
- "Published"
---
{%hackmd @CynthiaChuang/Github-Page-Theme %}
<br>
Given two strings `needle` and `haystack`, return the index of the first occurrence of `needle` in `haystack`, or `-1` if `needle` is not part of haystack.
<!--more-->
**Example 1:**
```
Input: haystack = "sadbutsad", needle = "sad"
Output: 0
Explanation: "sad" occurs at index 0 and 6.
The first occurrence is at index 0, so we return 0.
```
<br>
**Example 2:**
```
Input: haystack = "leetcode", needle = "leeto"
Output: -1
Explanation: "leeto" did not occur in "leetcode", so we return -1.
```
<br>
**Constraints:**
- 1 <= haystack.length, needle.length <= 104
- haystack and needle consist of only lowercase English characters.
**Related Topics:** `Two Pointers` `String` `String Matching`
## 解題邏輯與實作
這題看來是要找子字串第一次出現的位置,若無,則回傳 `-1`。最直覺的方法就是從左到右一一比過去,若剩餘長度小於子字串長度就中止。對了,開始前可以加上兩判斷式,若 `haystack` 或 `needle` 長度為 0,直接回傳 -1;若 `needle` 長度大於 `haystack` 也直接回傳 -1。
先照這樣的想法去寫一版:
```python=
def strStr(haystack: str, needle: str) -> int:
h_len = len(haystack)
n_len = len(needle)
if h_len < n_len:
return -1
if h_len == 0 or n_len ==0:
return -1
end_idx = h_len-n_len+1
for i in range(0, end_idx):
for j in range(0, n_len):
if haystack[i+j] != needle[j]:
break;
if j == n_len-1:
return i
return -1
```
是說,如果不是為了寫過程,我應該會直接呼叫 [`find`](https://www.w3schools.com/python/ref_string_find.asp) XDDD
```python=
def strStr(haystack: str, needle: str) -> int:
return haystack.rfind(needle)
```
<br>
依稀記得除了暴力搜尋外,應該還有一個從後面比的演算法,到[維基百科](https://zh.wikipedia.org/zh-tw/字串搜尋演算法)查了下,我印想中的應該是 [Boyer-Moore字串搜尋演算法](https://zh.wikipedia.org/wiki/博耶-穆尔字符串搜索算法)。所以我根據 [〈Boyer Moore Algorithm for Pattern Searching〉](https://www.geeksforgeeks.org/boyer-moore-algorithm-for-pattern-searching/)的教學實做了一次,但這份教學應該是 Boyer-Moore 演算法的精簡版本,因為它沒實做好字元位移規則的部份:
```python=
def badCharHeuristic(needle: str):
NO_OF_CHARS = 256
n_len = len(needle)
badChar = [-1]*NO_OF_CHARS
for i in range(n_len):
badChar[ord(needle[i])] = i;
return badChar
def strStr(haystack, needle):
h_len = len(haystack)
n_len = len(needle)
if h_len < n_len:
return -1
if h_len == 0 or n_len ==0:
return -1
badChar = badCharHeuristic(needle)
i = 0
end_idx = h_len-n_len
while(i <= end_idx):
j = n_len-1
while j>=0 and needle[j] == haystack[i+j]:
j -= 1
if j<0:
return i
else:
i += max(1, j-badChar[ord(haystack[i+j])])
return -1
```
## 其他連結
1. [【LeetCode】0000. 解題目錄](/@CynthiaChuang/LeetCode-0000-Contents)
## 更新紀錄
:::spoiler 最後更新日期:2023-02-15
- 2023-02-15 發布
- 2023-02-03 完稿
- 2023-02-03 起稿
:::
{%hackmd @CynthiaChuang/Github-Page-Footer %}