Skip to content

Commit 5ab6a1f

Browse files
committed
feat(strings): first occurrence
1 parent 9a88ed9 commit 5ab6a1f

File tree

5 files changed

+98
-0
lines changed

5 files changed

+98
-0
lines changed

pystrings/first_occurrence/README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Find the Index of the First Occurrence in a String
2+
3+
Given two strings needle and haystack, return the index of the first occurrence of needle in haystack, or -1 if needle
4+
is not part of haystack.
5+
6+
```text
7+
Example 1:
8+
9+
Input: haystack = "sadbutsad", needle = "sad"
10+
Output: 0
11+
Explanation: "sad" occurs at index 0 and 6.
12+
The first occurrence is at index 0, so we return 0.
13+
```
14+
15+
```text
16+
Example 2:
17+
18+
Input: haystack = "leetcode", needle = "leeto"
19+
Output: -1
20+
Explanation: "leeto" did not occur in "leetcode", so we return -1.
21+
```
22+
23+
## Related Topics
24+
25+
- Two pointers
26+
- String
27+
- String Matching
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from utils.benchmark import func_timer
2+
3+
4+
@func_timer
5+
def str_str(haystack: str, needle: str) -> int:
6+
# makes sure we don't iterate through a substring that is shorter than needle
7+
for i in range(len(haystack) - len(needle) + 1):
8+
# check if any substring of haystack with the same length as needle is equal to needle
9+
if haystack[i: i + len(needle)] == needle:
10+
# if yes, we return the first index of that substring
11+
return i
12+
# if we exit the loop, return -1
13+
return -1
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import unittest
2+
from . import str_str
3+
4+
5+
class StrStrTestCase(unittest.TestCase):
6+
def test_sadbutsad_sad(self):
7+
"""sadbutsad, needle = sad"""
8+
haystack = "sadbutsad"
9+
needle = "sad"
10+
expected = 0
11+
actual = str_str(haystack, needle)
12+
13+
self.assertEqual(expected, actual)
14+
15+
def test_leetcode_leeto(self):
16+
"""leetcode, needle = leeto"""
17+
haystack = "leetcode"
18+
needle = "leeto"
19+
expected = -1
20+
actual = str_str(haystack, needle)
21+
22+
self.assertEqual(expected, actual)
23+
24+
25+
if __name__ == '__main__':
26+
unittest.main()

utils/benchmark/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from .timer import func_timer
2+
3+
__all__ = [
4+
"func_timer"
5+
]

utils/benchmark/timer.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from typing import Callable
2+
import time
3+
4+
5+
def func_timer(func: Callable) -> Callable:
6+
"""
7+
Decorator function that times the execution of a function
8+
@param func: Function to time
9+
@return: Callable that wraps around the function to time
10+
"""
11+
12+
def timer(*args, **kwargs):
13+
"""
14+
Times a given function and passes in the arguments called on the function
15+
@param args:
16+
@param kwargs:
17+
@return:
18+
"""
19+
start = time.time()
20+
value = func(*args, **kwargs)
21+
end = time.time()
22+
runtime = end - start
23+
msg = "{func} took {time} seconds to complete its execution."
24+
print(msg.format(func=func.__name__, time=runtime))
25+
return value
26+
27+
return timer

0 commit comments

Comments
 (0)