diff --git a/README.md b/README.md index 89f4e1e..48bda65 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,4 @@ -# Lab-1 +# Lab 7 - Dynamic Programming -## Task -Implement a sorting algorithm - HeapSort(ascending/descending) +### Rabin Karp String Matching Algorithm -## Result output -- Algorithm's name -- Execution time -- Counters: swaps, comparisons -- Sorting result - -## Code must be covered with tests -- sort the input array -- sort in ascending order of sorted array in ascending order -- sort in descending order of sorted array in ascending order -- sort in ascending order of sorted array in descending order -- sort in descending order of sorted array in descending order - -## How to run -- 'cd' into folder where you want to store this repository -- Clone this repository with command 'git clone https://github.com/yeldmitrenko/Algorithms_Labs.git' -- Choose branch lab_1 with command 'git checkout lab_1' -- Go into folder with files with command 'cd Algorithms_Labs' -- run command 'python main.py' \ No newline at end of file diff --git a/heap_sort.py b/heap_sort.py deleted file mode 100644 index 5826411..0000000 --- a/heap_sort.py +++ /dev/null @@ -1,64 +0,0 @@ -import time - -compare_count = 0 -swap_count = 0 - - -def heapify(array, current_index, heap_size, sort_order): - global compare_count - global swap_count - - largest_element = current_index - left_child = 2 * current_index + 1 - right_child = 2 * current_index + 2 - - def compare(a, b): - if a >= b: - return 1 - else: - return -1 - - if left_child < heap_size and compare(array[left_child], array[largest_element]) != compare(sort_order, "desc"): - largest_element = left_child - compare_count += 4 - - if right_child < heap_size and compare(array[right_child], array[largest_element]) != compare(sort_order, "desc"): - largest_element = right_child - compare_count += 4 - - if largest_element != current_index: - array[current_index], array[largest_element] = array[largest_element], array[current_index] - compare_count += 1 - swap_count += 1 - heapify(array, largest_element, heap_size, sort_order) - - -def heap_sort(array, sort_order): - global swap_count - - array_length = len(array) - for i in range(array_length // 2, -1, -1): - heapify(array, i, array_length, sort_order) - - for i in range(array_length - 1, 0, -1): - array[i], array[0] = array[0], array[i] - heapify(array, 0, i, sort_order) - swap_count += 1 - - return array - - -if __name__ == "__main__": - sort_order = str(input("Enter sort order (asc or desc): ")) - array = [int(item) for item in input("Enter initial array: ").split(",")] - - start_time = time.perf_counter() - heap_sort(array, sort_order) - end_time = time.perf_counter() - execution_time = (end_time - start_time) * 1000 - print(f"Execution time: {execution_time} ms") - - print(f"Comparisons: {compare_count}") - print(f"Swaps: {swap_count}") - - print("Heap sort:", heap_sort(array, sort_order)) diff --git a/rabin_karp.py b/rabin_karp.py new file mode 100644 index 0000000..7cb8c4c --- /dev/null +++ b/rabin_karp.py @@ -0,0 +1,46 @@ +alphabet_size = 256 + + +def calculate_hash(pattern, primary_number): + reducing_hash_number = 1 + + for i in range(len(pattern) - 1): + reducing_hash_number = (reducing_hash_number * alphabet_size) % primary_number + + return reducing_hash_number + + +def rabin_karp_search(text, pattern, primary_number=101): + positions_array = [] + text_hash_value = 0 + pattern_hash_value = 0 + + reducing_hash_number = calculate_hash(pattern, primary_number) + + for i in range(len(pattern)): + text_hash_value = (alphabet_size * text_hash_value + ord(text[i])) % primary_number + pattern_hash_value = (alphabet_size * pattern_hash_value + ord(pattern[i])) % primary_number + + for i in range(len(text) - len(pattern) + 1): + if pattern_hash_value == text_hash_value: + matches_number = 0 + for j in range(len(pattern)): + if pattern[j] == text[j + i]: + matches_number += 1 + else: + break + if matches_number == len(pattern): + positions_array.append(i) + + if i < len(text) - len(pattern): + text_hash_value = (alphabet_size * (text_hash_value - ord(text[i]) * reducing_hash_number) + ord( + text[i + len(pattern)])) % primary_number + text_hash_value = text_hash_value + primary_number if text_hash_value < 0 else text_hash_value + return positions_array + + +if __name__ == '__main__': + text = "BBCLLNMNLLN" + pattern = "LLN" + + print(rabin_karp_search(text, pattern)) diff --git a/test.py b/test.py index cbeda88..bd9f4c3 100644 --- a/test.py +++ b/test.py @@ -1,28 +1,26 @@ import unittest -from heap_sort import heap_sort -from copy import deepcopy +from lab7.rabin_karp import rabin_karp_search -class TestHeapSort(unittest.TestCase): - def setUp(self) -> None: - self.array_example = [1, 2, 56, 45, -9, 78, 11] - self.array_sorted_asc = [-9, 1, 2, 11, 45, 56, 78] - self.array_sorted_desc = [78, 56, 45, 11, 2, 1, -9] - def test_sort_asc(self): - self.assertListEqual(heap_sort(deepcopy(self.array_example), "asc"), self.array_sorted_asc) +class RabinKarpTest(unittest.TestCase): + def setUp(self) -> None: + self.test_text1 = "AAA NN MM LL K AA" + self.test_pattern1 = "AA" + self.benchmark_positions_array1 = [0, 1, 15] - def test_sort_desc(self): - self.assertListEqual(heap_sort(deepcopy(self.array_example), "desc"), self.array_sorted_desc) + self.test_pattern2 = "LLN" + self.test_text2 = "BBCLLNMNLLN" + self.benchmark_positions_array2 = [3, 8] - def test_sort_asc_in_asc(self): - self.assertListEqual(heap_sort(deepcopy(self.array_sorted_asc), "asc"), self.array_sorted_asc) + def test_rabin_karp_search_1(self): + pattern_positions = rabin_karp_search(self.test_text1, self.test_pattern1) + self.assertEqual(pattern_positions, self.benchmark_positions_array1) - def test_sort_asc_in_desc(self): - self.assertListEqual(heap_sort(deepcopy(self.array_sorted_asc), "desc"), self.array_sorted_desc) + def test_rabin_karp_search_2(self): + pattern_positions = rabin_karp_search(self.test_text2, self.test_pattern2) + self.assertEqual(pattern_positions, self.benchmark_positions_array2) - def test_sort_desc_in_asc(self): - self.assertListEqual(heap_sort(deepcopy(self.array_sorted_desc), "asc"), self.array_sorted_asc) - def test_sort_desc_in_desc(self): - self.assertListEqual(heap_sort(deepcopy(self.array_sorted_desc), "desc"), self.array_sorted_desc) +if __name__ == '__main__': + unittest.main()