Skip to content
This repository was archived by the owner on Jul 2, 2024. It is now read-only.

Commit e95529c

Browse files
committed
Added binary search package
Added "find prefix" problem set. Implemented straight-forward approach and test cases. Test fixtures are generated using https://random.org/
1 parent bdf8174 commit e95529c

File tree

8 files changed

+10111
-0
lines changed

8 files changed

+10111
-0
lines changed

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ classifiers = [
3232
"Topic :: Education",
3333
]
3434
packages = [
35+
{ include = "bisearch", from = "src" },
3536
{ include = "conv_store", from = "src" },
3637
{ include = "sequences", from = "src" },
3738
{ include = "sorting", from = "src" },

src/bisearch/__init__.py

Whitespace-only changes.

src/bisearch/prefix.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
from typing import List
2+
3+
4+
def bisect_right(origin: List[str], search: str = "") -> int:
5+
"""Return the most right index
6+
7+
:param origin: a list of strings
8+
:type origin: list[str]
9+
:param search: a prefix to search
10+
:type search: str
11+
12+
:return: the index of the first string starting with search prefix
13+
:rtype: int
14+
15+
"""
16+
17+
low: int = 0
18+
high: int = len(origin)
19+
prefix_size: int = len(search)
20+
21+
while low < high:
22+
idx = low + (high - low) // 2 # the same as (high + low) // 2
23+
cur = origin[idx][:prefix_size]
24+
25+
if cur <= search:
26+
low = idx + 1
27+
else:
28+
high = idx
29+
30+
return low
31+
32+
33+
def bisect_left(origin: List[str], search: str = "") -> int:
34+
"""Return the most left index
35+
36+
:param origin: a list of strings
37+
:type origin: list[str]
38+
:param search: a prefix to search
39+
:type search: str
40+
41+
:return: the index after the last string starting with search prefix
42+
:rtype: int
43+
44+
"""
45+
46+
low: int = 0
47+
high: int = len(origin)
48+
prefix_size: int = len(search)
49+
50+
while low < high:
51+
idx = low + (high - low) // 2 # the same as (high + low) // 2
52+
cur = origin[idx][:prefix_size]
53+
54+
if cur < search:
55+
low = idx + 1
56+
else:
57+
high = idx
58+
59+
return low
60+
61+
62+
def find_all(origin: List[str], search: str = "") -> List[str]:
63+
start = bisect_left(origin, search)
64+
end = bisect_right(origin, search)
65+
66+
return origin[start:end]

src/bisearch/py.typed

Whitespace-only changes.

tests/bisearch/__init__.py

Whitespace-only changes.

tests/bisearch/conftest.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from pathlib import Path
2+
3+
import pytest
4+
5+
6+
@pytest.fixture
7+
def strings_fixtures():
8+
fixture_path = Path(__file__).parent.joinpath("fixtures/strings.txt")
9+
with open(fixture_path) as fixture_file:
10+
return fixture_file.read().splitlines()
11+
12+
13+
@pytest.fixture
14+
def fa_fixture():
15+
return (
16+
"ua",
17+
["uaeafwqbag", "uasyolgnuc", "uaszazvdez", "uavmfgakey", "uawwitgssy",
18+
"uaxxgxmsrn", "uayppkjtny", ]
19+
)
20+
21+
22+
@pytest.fixture
23+
def pr_fixture():
24+
return "sh", 7045
25+
26+
27+
@pytest.fixture
28+
def pl_fixture():
29+
return "vp", 8291

0 commit comments

Comments
 (0)