From af079f9895c3b33fddea2d146c5f05a3f5486618 Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Wed, 9 Oct 2024 11:44:30 +0530 Subject: [PATCH 01/12] Add tests, remove `main, improve docs` in `ExponentialSearch` --- .../searches/ExponentalSearch.java | 59 ++++++------ .../searches/ExponentialSearchTest.java | 90 +++++++++++++++++++ 2 files changed, 121 insertions(+), 28 deletions(-) create mode 100644 src/test/java/com/thealgorithms/searches/ExponentialSearchTest.java diff --git a/src/main/java/com/thealgorithms/searches/ExponentalSearch.java b/src/main/java/com/thealgorithms/searches/ExponentalSearch.java index a856bd659720..9187dcbc2f4b 100644 --- a/src/main/java/com/thealgorithms/searches/ExponentalSearch.java +++ b/src/main/java/com/thealgorithms/searches/ExponentalSearch.java @@ -2,44 +2,47 @@ import com.thealgorithms.devutils.searches.SearchAlgorithm; import java.util.Arrays; -import java.util.Random; -import java.util.concurrent.ThreadLocalRandom; -import java.util.stream.IntStream; +/** + * ExponentialSearch is an algorithm that efficiently finds the position of a target + * value within a sorted array. It works by expanding the range to find the bounds + * where the target might exist and then using binary search within that range. + * + *

+ * Worst-case time complexity: O(log n) + * Best-case time complexity: O(1) when the element is found at the first position. + * Average time complexity: O(log n) + * Worst-case space complexity: O(1) + *

+ * + *

+ * Note: This algorithm requires that the input array be sorted. + *

+ */ class ExponentialSearch implements SearchAlgorithm { - public static void main(String[] args) { - Random r = ThreadLocalRandom.current(); - - int size = 100; - int maxElement = 100000; - - Integer[] integers = IntStream.generate(() -> r.nextInt(maxElement)).limit(size).sorted().boxed().toArray(Integer[] ::new); - - // The element that should be found - int shouldBeFound = integers[r.nextInt(size - 1)]; - - ExponentialSearch search = new ExponentialSearch(); - int atIndex = search.find(integers, shouldBeFound); - - System.out.printf("Should be found: %d. Found %d at index %d. An array length %d%n", shouldBeFound, integers[atIndex], atIndex, size); - - int toCheck = Arrays.binarySearch(integers, shouldBeFound); - System.out.printf("Found by system method at an index: %d. Is equal: %b%n", toCheck, toCheck == atIndex); - } - + /** + * Finds the index of the specified key in a sorted array using exponential search. + * + * @param array The sorted array to search. + * @param key The element to search for. + * @param The type of the elements in the array, which must be comparable. + * @return The index of the key if found, otherwise -1. + */ @Override public > int find(T[] array, T key) { - if (array[0] == key) { + if (array.length == 0) { + return -1; + } + if (array[0].equals(key)) { return 0; } - if (array[array.length - 1] == key) { - return array.length; + if (array[array.length - 1].equals(key)) { + return array.length - 1; } int range = 1; - - while (range < array.length && array[range].compareTo(key) <= -1) { + while (range < array.length && array[range].compareTo(key) < 0) { range = range * 2; } diff --git a/src/test/java/com/thealgorithms/searches/ExponentialSearchTest.java b/src/test/java/com/thealgorithms/searches/ExponentialSearchTest.java new file mode 100644 index 000000000000..696c5000bf96 --- /dev/null +++ b/src/test/java/com/thealgorithms/searches/ExponentialSearchTest.java @@ -0,0 +1,90 @@ +package com.thealgorithms.searches; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.stream.IntStream; +import org.junit.jupiter.api.Test; + +/** + * Unit tests for the ExponentialSearch class. + */ +class ExponentialSearchTest { + + /** + * Test for basic exponential search functionality. + */ + @Test + void testExponentialSearchFound() { + ExponentialSearch exponentialSearch = new ExponentialSearch(); + Integer[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + int key = 7; + int expectedIndex = 6; // Index of the key in the array + assertEquals(expectedIndex, exponentialSearch.find(array, key), + "The index of the found element should be 6."); + } + + /** + * Test for exponential search with the first element as the key. + */ + @Test + void testExponentialSearchFirstElement() { + ExponentialSearch exponentialSearch = new ExponentialSearch(); + Integer[] array = {1, 2, 3, 4, 5}; + int key = 1; // First element + int expectedIndex = 0; // Index of the key in the array + assertEquals(expectedIndex, exponentialSearch.find(array, key), + "The index of the first element should be 0."); + } + + /** + * Test for exponential search with the last element as the key. + */ + @Test + void testExponentialSearchLastElement() { + ExponentialSearch exponentialSearch = new ExponentialSearch(); + Integer[] array = {1, 2, 3, 4, 5}; + int key = 5; // Last element + int expectedIndex = 4; // Index of the key in the array + assertEquals(expectedIndex, exponentialSearch.find(array, key), + "The index of the last element should be 4."); + } + + /** + * Test for exponential search with a single element present. + */ + @Test + void testExponentialSearchSingleElementFound() { + ExponentialSearch exponentialSearch = new ExponentialSearch(); + Integer[] array = {1}; + int key = 1; // Only element present + int expectedIndex = 0; // Index of the key in the array + assertEquals(expectedIndex, exponentialSearch.find(array, key), + "The index of the single element should be 0."); + } + + /** + * Test for exponential search with an empty array. + */ + @Test + void testExponentialSearchEmptyArray() { + ExponentialSearch exponentialSearch = new ExponentialSearch(); + Integer[] array = {}; // Empty array + int key = 1; // Key not present + int expectedIndex = -1; // Key not found + assertEquals(expectedIndex, exponentialSearch.find(array, key), + "The element should not be found in an empty array."); + } + + /** + * Test for exponential search on large array. + */ + @Test + void testExponentialSearchLargeArray() { + ExponentialSearch exponentialSearch = new ExponentialSearch(); + Integer[] array = IntStream.range(0, 10000).boxed().toArray(Integer[]::new); // Array from 0 to 9999 + int key = 9999; // Last element + int expectedIndex = 9999; // Index of the last element + assertEquals(expectedIndex, exponentialSearch.find(array, key), + "The index of the last element should be 9999."); + } +} From 166855b711641d4064762fc42f651248764d5e9d Mon Sep 17 00:00:00 2001 From: Hardvan Date: Wed, 9 Oct 2024 06:15:08 +0000 Subject: [PATCH 02/12] Update directory --- DIRECTORY.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 6042dd1b5e0d..0fd1ebe62897 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -31,6 +31,7 @@ * [IsPowerTwo](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/IsPowerTwo.java) * [LowestSetBit](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/LowestSetBit.java) * [NonRepeatingNumberFinder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinder.java) + * [NumberAppearingOddTimes](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/NumberAppearingOddTimes.java) * [NumbersDifferentSigns](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/NumbersDifferentSigns.java) * [ReverseBits](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/ReverseBits.java) * [SingleBitOperations](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/SingleBitOperations.java) @@ -638,6 +639,7 @@ * [IsPowerTwoTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/IsPowerTwoTest.java) * [LowestSetBitTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/LowestSetBitTest.java) * [NonRepeatingNumberFinderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinderTest.java) + * [NumberAppearingOddTimesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/NumberAppearingOddTimesTest.java) * [NumbersDifferentSignsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/NumbersDifferentSignsTest.java) * [ReverseBitsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/ReverseBitsTest.java) * [SingleBitOperationsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/SingleBitOperationsTest.java) @@ -968,6 +970,7 @@ * [BM25InvertedIndexTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/BM25InvertedIndexTest.java) * [BreadthFirstSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/BreadthFirstSearchTest.java) * [DepthFirstSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/DepthFirstSearchTest.java) + * [ExponentialSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/ExponentialSearchTest.java) * [HowManyTimesRotatedTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/HowManyTimesRotatedTest.java) * [KMPSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/KMPSearchTest.java) * [OrderAgnosticBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/OrderAgnosticBinarySearchTest.java) From 4be2a85fd12bfda00e42f487fe7b04b5c21b831a Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Wed, 9 Oct 2024 11:46:10 +0530 Subject: [PATCH 03/12] Fix --- .../searches/ExponentialSearchTest.java | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/test/java/com/thealgorithms/searches/ExponentialSearchTest.java b/src/test/java/com/thealgorithms/searches/ExponentialSearchTest.java index 696c5000bf96..f95db2a185b9 100644 --- a/src/test/java/com/thealgorithms/searches/ExponentialSearchTest.java +++ b/src/test/java/com/thealgorithms/searches/ExponentialSearchTest.java @@ -19,8 +19,7 @@ void testExponentialSearchFound() { Integer[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int key = 7; int expectedIndex = 6; // Index of the key in the array - assertEquals(expectedIndex, exponentialSearch.find(array, key), - "The index of the found element should be 6."); + assertEquals(expectedIndex, exponentialSearch.find(array, key), "The index of the found element should be 6."); } /** @@ -32,8 +31,7 @@ void testExponentialSearchFirstElement() { Integer[] array = {1, 2, 3, 4, 5}; int key = 1; // First element int expectedIndex = 0; // Index of the key in the array - assertEquals(expectedIndex, exponentialSearch.find(array, key), - "The index of the first element should be 0."); + assertEquals(expectedIndex, exponentialSearch.find(array, key), "The index of the first element should be 0."); } /** @@ -45,8 +43,7 @@ void testExponentialSearchLastElement() { Integer[] array = {1, 2, 3, 4, 5}; int key = 5; // Last element int expectedIndex = 4; // Index of the key in the array - assertEquals(expectedIndex, exponentialSearch.find(array, key), - "The index of the last element should be 4."); + assertEquals(expectedIndex, exponentialSearch.find(array, key), "The index of the last element should be 4."); } /** @@ -58,8 +55,7 @@ void testExponentialSearchSingleElementFound() { Integer[] array = {1}; int key = 1; // Only element present int expectedIndex = 0; // Index of the key in the array - assertEquals(expectedIndex, exponentialSearch.find(array, key), - "The index of the single element should be 0."); + assertEquals(expectedIndex, exponentialSearch.find(array, key), "The index of the single element should be 0."); } /** @@ -71,8 +67,7 @@ void testExponentialSearchEmptyArray() { Integer[] array = {}; // Empty array int key = 1; // Key not present int expectedIndex = -1; // Key not found - assertEquals(expectedIndex, exponentialSearch.find(array, key), - "The element should not be found in an empty array."); + assertEquals(expectedIndex, exponentialSearch.find(array, key), "The element should not be found in an empty array."); } /** @@ -84,7 +79,6 @@ void testExponentialSearchLargeArray() { Integer[] array = IntStream.range(0, 10000).boxed().toArray(Integer[]::new); // Array from 0 to 9999 int key = 9999; // Last element int expectedIndex = 9999; // Index of the last element - assertEquals(expectedIndex, exponentialSearch.find(array, key), - "The index of the last element should be 9999."); + assertEquals(expectedIndex, exponentialSearch.find(array, key), "The index of the last element should be 9999."); } } From e69d42a0a14f4a83d4a2ae2e0b0b31a45975dbea Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Wed, 9 Oct 2024 11:53:49 +0530 Subject: [PATCH 04/12] Add tests, remove `main`, improve docs in `ExponentialSearch` --- .../searches/FibonacciSearch.java | 55 +++++--- .../searches/FibonacciSearchTest.java | 124 ++++++++++++++++++ 2 files changed, 159 insertions(+), 20 deletions(-) create mode 100644 src/test/java/com/thealgorithms/searches/FibonacciSearchTest.java diff --git a/src/main/java/com/thealgorithms/searches/FibonacciSearch.java b/src/main/java/com/thealgorithms/searches/FibonacciSearch.java index 028ab07e0a86..2124938bc258 100644 --- a/src/main/java/com/thealgorithms/searches/FibonacciSearch.java +++ b/src/main/java/com/thealgorithms/searches/FibonacciSearch.java @@ -2,24 +2,42 @@ import com.thealgorithms.devutils.searches.SearchAlgorithm; -/* - * Fibonacci Search is a popular algorithm which finds the position of a target value in - * a sorted array +/** + * FibonacciSearch is a search algorithm that finds the position of a target value in + * a sorted array using Fibonacci numbers. * - * The time complexity for this search algorithm is O(log3(n)) - * The space complexity for this search algorithm is O(1) - * @author Kanakalatha Vemuru (https://github.com/KanakalathaVemuru) + *

+ * The time complexity for this search algorithm is O(log n). + * The space complexity for this search algorithm is O(1). + *

+ * + *

+ * Note: This algorithm requires that the input array be sorted. + *

*/ public class FibonacciSearch implements SearchAlgorithm { /** - * @param array is a sorted array where the element has to be searched - * @param key is an element whose position has to be found - * @param is any comparable type - * @return index of the element + * Finds the index of the specified key in a sorted array using Fibonacci search. + * + * @param array The sorted array to search. + * @param key The element to search for. + * @param The type of the elements in the array, which must be comparable. + * @throws IllegalArgumentException if the input array is not sorted or empty, or if the key is null. + * @return The index of the key if found, otherwise -1. */ @Override public > int find(T[] array, T key) { + if (array.length == 0) { + throw new IllegalArgumentException("Input array must not be empty."); + } + if (!isSorted(array)) { + throw new IllegalArgumentException("Input array must be sorted."); + } + if (key == null) { + throw new IllegalArgumentException("Key must not be null."); + } + int fibMinus1 = 1; int fibMinus2 = 0; int fibNumber = fibMinus1 + fibMinus2; @@ -57,15 +75,12 @@ public > int find(T[] array, T key) { return -1; } - // Driver Program - public static void main(String[] args) { - Integer[] integers = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512}; - - int size = integers.length; - Integer targetValue = 128; - FibonacciSearch fsearch = new FibonacciSearch(); - int atIndex = fsearch.find(integers, targetValue); - - System.out.println("Should be found: " + targetValue + ". Found " + integers[atIndex] + " at index " + atIndex + ". An array length " + size); + private boolean isSorted(Comparable[] array) { + for (int i = 1; i < array.length; i++) { + if (array[i - 1].compareTo(array[i]) > 0) { + return false; + } + } + return true; } } diff --git a/src/test/java/com/thealgorithms/searches/FibonacciSearchTest.java b/src/test/java/com/thealgorithms/searches/FibonacciSearchTest.java new file mode 100644 index 000000000000..8f7916a6378b --- /dev/null +++ b/src/test/java/com/thealgorithms/searches/FibonacciSearchTest.java @@ -0,0 +1,124 @@ +package com.thealgorithms.searches; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.stream.IntStream; +import org.junit.jupiter.api.Test; + +/** + * Unit tests for the FibonacciSearch class. + */ +class FibonacciSearchTest { + + /** + * Test for basic Fibonacci search functionality. + */ + @Test + void testFibonacciSearchFound() { + FibonacciSearch fibonacciSearch = new FibonacciSearch(); + Integer[] array = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512}; + int key = 128; + int expectedIndex = 7; // Index of the key in the array + assertEquals(expectedIndex, fibonacciSearch.find(array, key), "The index of the found element should be 7."); + } + + /** + * Test for Fibonacci search when the element is not present. + */ + @Test + void testFibonacciSearchNotFound() { + FibonacciSearch fibonacciSearch = new FibonacciSearch(); + Integer[] array = {1, 2, 4, 8, 16}; + int key = 6; // Element not present in the array + int expectedIndex = -1; // Key not found + assertEquals(expectedIndex, fibonacciSearch.find(array, key), "The element should not be found in the array."); + } + + /** + * Test for Fibonacci search with the first element as the key. + */ + @Test + void testFibonacciSearchFirstElement() { + FibonacciSearch fibonacciSearch = new FibonacciSearch(); + Integer[] array = {1, 2, 4, 8, 16}; + int key = 1; // First element + int expectedIndex = 0; // Index of the key in the array + assertEquals(expectedIndex, fibonacciSearch.find(array, key), "The index of the first element should be 0."); + } + + /** + * Test for Fibonacci search with the last element as the key. + */ + @Test + void testFibonacciSearchLastElement() { + FibonacciSearch fibonacciSearch = new FibonacciSearch(); + Integer[] array = {1, 2, 4, 8, 16}; + int key = 16; // Last element + int expectedIndex = 4; // Index of the key in the array + assertEquals(expectedIndex, fibonacciSearch.find(array, key), "The index of the last element should be 4."); + } + + /** + * Test for Fibonacci search with a single element present. + */ + @Test + void testFibonacciSearchSingleElementFound() { + FibonacciSearch fibonacciSearch = new FibonacciSearch(); + Integer[] array = {1}; + int key = 1; // Only element present + int expectedIndex = 0; // Index of the key in the array + assertEquals(expectedIndex, fibonacciSearch.find(array, key), "The index of the single element should be 0."); + } + + /** + * Test for Fibonacci search with a single element not present. + */ + @Test + void testFibonacciSearchSingleElementNotFound() { + FibonacciSearch fibonacciSearch = new FibonacciSearch(); + Integer[] array = {1}; + int key = 2; // Key not present + int expectedIndex = -1; // Key not found + assertEquals(expectedIndex, fibonacciSearch.find(array, key), "The element should not be found in the array."); + } + + /** + * Test for Fibonacci search with an empty array. + */ + @Test + void testFibonacciSearchEmptyArray() { + FibonacciSearch fibonacciSearch = new FibonacciSearch(); + Integer[] array = {}; // Empty array + int key = 1; // Key not present + assertThrows(IllegalArgumentException.class, () -> fibonacciSearch.find(array, key), "An empty array should throw an IllegalArgumentException."); + } + + @Test + void testFibonacciSearchUnsortedArray() { + FibonacciSearch fibonacciSearch = new FibonacciSearch(); + Integer[] array = {2, 1, 4, 3, 6, 5}; + int key = 3; // Key not present + assertThrows(IllegalArgumentException.class, () -> fibonacciSearch.find(array, key), "An unsorted array should throw an IllegalArgumentException."); + } + + @Test + void testFibonacciSearchNullKey() { + FibonacciSearch fibonacciSearch = new FibonacciSearch(); + Integer[] array = {1, 2, 4, 8, 16}; + Integer key = null; // Null key + assertThrows(IllegalArgumentException.class, () -> fibonacciSearch.find(array, key), "A null key should throw an IllegalArgumentException."); + } + + /** + * Test for Fibonacci search on large array. + */ + @Test + void testFibonacciSearchLargeArray() { + FibonacciSearch fibonacciSearch = new FibonacciSearch(); + Integer[] array = IntStream.range(0, 10000).boxed().toArray(Integer[]::new); // Array from 0 to 9999 + int key = 9999; // Last element + int expectedIndex = 9999; // Index of the last element + assertEquals(expectedIndex, fibonacciSearch.find(array, key), "The index of the last element should be 9999."); + } +} From 4c13356248ffe0d0bd13c3def31b1dfe14f53e72 Mon Sep 17 00:00:00 2001 From: Hardvan Date: Wed, 9 Oct 2024 06:24:16 +0000 Subject: [PATCH 05/12] Update directory --- DIRECTORY.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 6042dd1b5e0d..a20d36cc08bb 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -31,6 +31,7 @@ * [IsPowerTwo](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/IsPowerTwo.java) * [LowestSetBit](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/LowestSetBit.java) * [NonRepeatingNumberFinder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinder.java) + * [NumberAppearingOddTimes](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/NumberAppearingOddTimes.java) * [NumbersDifferentSigns](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/NumbersDifferentSigns.java) * [ReverseBits](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/ReverseBits.java) * [SingleBitOperations](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/SingleBitOperations.java) @@ -638,6 +639,7 @@ * [IsPowerTwoTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/IsPowerTwoTest.java) * [LowestSetBitTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/LowestSetBitTest.java) * [NonRepeatingNumberFinderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinderTest.java) + * [NumberAppearingOddTimesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/NumberAppearingOddTimesTest.java) * [NumbersDifferentSignsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/NumbersDifferentSignsTest.java) * [ReverseBitsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/ReverseBitsTest.java) * [SingleBitOperationsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/SingleBitOperationsTest.java) @@ -968,6 +970,7 @@ * [BM25InvertedIndexTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/BM25InvertedIndexTest.java) * [BreadthFirstSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/BreadthFirstSearchTest.java) * [DepthFirstSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/DepthFirstSearchTest.java) + * [FibonacciSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/FibonacciSearchTest.java) * [HowManyTimesRotatedTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/HowManyTimesRotatedTest.java) * [KMPSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/KMPSearchTest.java) * [OrderAgnosticBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/OrderAgnosticBinarySearchTest.java) From 22a657380ad74cddee23f6c9024e57813a1344bd Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Wed, 9 Oct 2024 11:54:57 +0530 Subject: [PATCH 06/12] Fix --- .../java/com/thealgorithms/searches/ExponentialSearchTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/thealgorithms/searches/ExponentialSearchTest.java b/src/test/java/com/thealgorithms/searches/ExponentialSearchTest.java index f95db2a185b9..b9822b94256a 100644 --- a/src/test/java/com/thealgorithms/searches/ExponentialSearchTest.java +++ b/src/test/java/com/thealgorithms/searches/ExponentialSearchTest.java @@ -76,7 +76,7 @@ void testExponentialSearchEmptyArray() { @Test void testExponentialSearchLargeArray() { ExponentialSearch exponentialSearch = new ExponentialSearch(); - Integer[] array = IntStream.range(0, 10000).boxed().toArray(Integer[]::new); // Array from 0 to 9999 + Integer[] array = IntStream.range(0, 10000).boxed().toArray(Integer[] ::new); // Array from 0 to 9999 int key = 9999; // Last element int expectedIndex = 9999; // Index of the last element assertEquals(expectedIndex, exponentialSearch.find(array, key), "The index of the last element should be 9999."); From edeb23af40a36f63da88961067ac8d91d189fca4 Mon Sep 17 00:00:00 2001 From: Hardvan Date: Wed, 9 Oct 2024 06:26:41 +0000 Subject: [PATCH 07/12] Update directory --- DIRECTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 0fd1ebe62897..425cde745473 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -971,6 +971,7 @@ * [BreadthFirstSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/BreadthFirstSearchTest.java) * [DepthFirstSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/DepthFirstSearchTest.java) * [ExponentialSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/ExponentialSearchTest.java) + * [FibonacciSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/FibonacciSearchTest.java) * [HowManyTimesRotatedTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/HowManyTimesRotatedTest.java) * [KMPSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/KMPSearchTest.java) * [OrderAgnosticBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/OrderAgnosticBinarySearchTest.java) From 6cad5a24ac6b0819c14fa985461c3fe8c636a1ae Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Wed, 9 Oct 2024 11:58:01 +0530 Subject: [PATCH 08/12] Fix --- .../com/thealgorithms/searches/ExponentialSearchTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/thealgorithms/searches/ExponentialSearchTest.java b/src/test/java/com/thealgorithms/searches/ExponentialSearchTest.java index b9822b94256a..c84da531e8a4 100644 --- a/src/test/java/com/thealgorithms/searches/ExponentialSearchTest.java +++ b/src/test/java/com/thealgorithms/searches/ExponentialSearchTest.java @@ -77,8 +77,8 @@ void testExponentialSearchEmptyArray() { void testExponentialSearchLargeArray() { ExponentialSearch exponentialSearch = new ExponentialSearch(); Integer[] array = IntStream.range(0, 10000).boxed().toArray(Integer[] ::new); // Array from 0 to 9999 - int key = 9999; // Last element - int expectedIndex = 9999; // Index of the last element + int key = 9999; + int expectedIndex = 9999; assertEquals(expectedIndex, exponentialSearch.find(array, key), "The index of the last element should be 9999."); } } From 135b1ed6cdc699c3109f783c5b519523e0341753 Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Wed, 9 Oct 2024 12:01:47 +0530 Subject: [PATCH 09/12] Fix --- .../searches/FibonacciSearch.java | 61 ++++++------------- 1 file changed, 20 insertions(+), 41 deletions(-) diff --git a/src/main/java/com/thealgorithms/searches/FibonacciSearch.java b/src/main/java/com/thealgorithms/searches/FibonacciSearch.java index 2124938bc258..1f645638835a 100644 --- a/src/main/java/com/thealgorithms/searches/FibonacciSearch.java +++ b/src/main/java/com/thealgorithms/searches/FibonacciSearch.java @@ -2,58 +2,36 @@ import com.thealgorithms.devutils.searches.SearchAlgorithm; -/** - * FibonacciSearch is a search algorithm that finds the position of a target value in - * a sorted array using Fibonacci numbers. +/* + * Fibonacci Search is a popular algorithm which finds the position of a target value in + * a sorted array * - *

- * The time complexity for this search algorithm is O(log n). - * The space complexity for this search algorithm is O(1). - *

- * - *

- * Note: This algorithm requires that the input array be sorted. - *

+ * The time complexity for this search algorithm is O(log3(n)) + * The space complexity for this search algorithm is O(1) + * @author Kanakalatha Vemuru (https://github.com/KanakalathaVemuru) */ public class FibonacciSearch implements SearchAlgorithm { /** - * Finds the index of the specified key in a sorted array using Fibonacci search. - * - * @param array The sorted array to search. - * @param key The element to search for. - * @param The type of the elements in the array, which must be comparable. - * @throws IllegalArgumentException if the input array is not sorted or empty, or if the key is null. - * @return The index of the key if found, otherwise -1. + * @param array is a sorted array where the element has to be searched + * @param key is an element whose position has to be found + * @param is any comparable type + * @return index of the element */ @Override public > int find(T[] array, T key) { - if (array.length == 0) { - throw new IllegalArgumentException("Input array must not be empty."); - } - if (!isSorted(array)) { - throw new IllegalArgumentException("Input array must be sorted."); - } - if (key == null) { - throw new IllegalArgumentException("Key must not be null."); - } - int fibMinus1 = 1; int fibMinus2 = 0; int fibNumber = fibMinus1 + fibMinus2; int n = array.length; - while (fibNumber < n) { fibMinus2 = fibMinus1; fibMinus1 = fibNumber; fibNumber = fibMinus2 + fibMinus1; } - int offset = -1; - while (fibNumber > 1) { int i = Math.min(offset + fibMinus2, n - 1); - if (array[i].compareTo(key) < 0) { fibNumber = fibMinus1; fibMinus1 = fibMinus2; @@ -67,20 +45,21 @@ public > int find(T[] array, T key) { return i; } } - if (fibMinus1 == 1 && array[offset + 1] == key) { return offset + 1; } - return -1; } - private boolean isSorted(Comparable[] array) { - for (int i = 1; i < array.length; i++) { - if (array[i - 1].compareTo(array[i]) > 0) { - return false; - } - } - return true; + // Driver Program + public static void main(String[] args) { + Integer[] integers = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512}; + + int size = integers.length; + Integer targetValue = 128; + FibonacciSearch fsearch = new FibonacciSearch(); + int atIndex = fsearch.find(integers, targetValue); + + System.out.println("Should be found: " + targetValue + ". Found " + integers[atIndex] + " at index " + atIndex + ". An array length " + size); } } From 5fab8464ba3fc88e3218ae143c4f44069640e2f5 Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Wed, 9 Oct 2024 12:02:01 +0530 Subject: [PATCH 10/12] Fix --- .../searches/FibonacciSearchTest.java | 124 ------------------ 1 file changed, 124 deletions(-) delete mode 100644 src/test/java/com/thealgorithms/searches/FibonacciSearchTest.java diff --git a/src/test/java/com/thealgorithms/searches/FibonacciSearchTest.java b/src/test/java/com/thealgorithms/searches/FibonacciSearchTest.java deleted file mode 100644 index 8f7916a6378b..000000000000 --- a/src/test/java/com/thealgorithms/searches/FibonacciSearchTest.java +++ /dev/null @@ -1,124 +0,0 @@ -package com.thealgorithms.searches; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import java.util.stream.IntStream; -import org.junit.jupiter.api.Test; - -/** - * Unit tests for the FibonacciSearch class. - */ -class FibonacciSearchTest { - - /** - * Test for basic Fibonacci search functionality. - */ - @Test - void testFibonacciSearchFound() { - FibonacciSearch fibonacciSearch = new FibonacciSearch(); - Integer[] array = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512}; - int key = 128; - int expectedIndex = 7; // Index of the key in the array - assertEquals(expectedIndex, fibonacciSearch.find(array, key), "The index of the found element should be 7."); - } - - /** - * Test for Fibonacci search when the element is not present. - */ - @Test - void testFibonacciSearchNotFound() { - FibonacciSearch fibonacciSearch = new FibonacciSearch(); - Integer[] array = {1, 2, 4, 8, 16}; - int key = 6; // Element not present in the array - int expectedIndex = -1; // Key not found - assertEquals(expectedIndex, fibonacciSearch.find(array, key), "The element should not be found in the array."); - } - - /** - * Test for Fibonacci search with the first element as the key. - */ - @Test - void testFibonacciSearchFirstElement() { - FibonacciSearch fibonacciSearch = new FibonacciSearch(); - Integer[] array = {1, 2, 4, 8, 16}; - int key = 1; // First element - int expectedIndex = 0; // Index of the key in the array - assertEquals(expectedIndex, fibonacciSearch.find(array, key), "The index of the first element should be 0."); - } - - /** - * Test for Fibonacci search with the last element as the key. - */ - @Test - void testFibonacciSearchLastElement() { - FibonacciSearch fibonacciSearch = new FibonacciSearch(); - Integer[] array = {1, 2, 4, 8, 16}; - int key = 16; // Last element - int expectedIndex = 4; // Index of the key in the array - assertEquals(expectedIndex, fibonacciSearch.find(array, key), "The index of the last element should be 4."); - } - - /** - * Test for Fibonacci search with a single element present. - */ - @Test - void testFibonacciSearchSingleElementFound() { - FibonacciSearch fibonacciSearch = new FibonacciSearch(); - Integer[] array = {1}; - int key = 1; // Only element present - int expectedIndex = 0; // Index of the key in the array - assertEquals(expectedIndex, fibonacciSearch.find(array, key), "The index of the single element should be 0."); - } - - /** - * Test for Fibonacci search with a single element not present. - */ - @Test - void testFibonacciSearchSingleElementNotFound() { - FibonacciSearch fibonacciSearch = new FibonacciSearch(); - Integer[] array = {1}; - int key = 2; // Key not present - int expectedIndex = -1; // Key not found - assertEquals(expectedIndex, fibonacciSearch.find(array, key), "The element should not be found in the array."); - } - - /** - * Test for Fibonacci search with an empty array. - */ - @Test - void testFibonacciSearchEmptyArray() { - FibonacciSearch fibonacciSearch = new FibonacciSearch(); - Integer[] array = {}; // Empty array - int key = 1; // Key not present - assertThrows(IllegalArgumentException.class, () -> fibonacciSearch.find(array, key), "An empty array should throw an IllegalArgumentException."); - } - - @Test - void testFibonacciSearchUnsortedArray() { - FibonacciSearch fibonacciSearch = new FibonacciSearch(); - Integer[] array = {2, 1, 4, 3, 6, 5}; - int key = 3; // Key not present - assertThrows(IllegalArgumentException.class, () -> fibonacciSearch.find(array, key), "An unsorted array should throw an IllegalArgumentException."); - } - - @Test - void testFibonacciSearchNullKey() { - FibonacciSearch fibonacciSearch = new FibonacciSearch(); - Integer[] array = {1, 2, 4, 8, 16}; - Integer key = null; // Null key - assertThrows(IllegalArgumentException.class, () -> fibonacciSearch.find(array, key), "A null key should throw an IllegalArgumentException."); - } - - /** - * Test for Fibonacci search on large array. - */ - @Test - void testFibonacciSearchLargeArray() { - FibonacciSearch fibonacciSearch = new FibonacciSearch(); - Integer[] array = IntStream.range(0, 10000).boxed().toArray(Integer[]::new); // Array from 0 to 9999 - int key = 9999; // Last element - int expectedIndex = 9999; // Index of the last element - assertEquals(expectedIndex, fibonacciSearch.find(array, key), "The index of the last element should be 9999."); - } -} From e371924dba9b467bda5a926f2072426c21ba4d87 Mon Sep 17 00:00:00 2001 From: Hardvan Date: Wed, 9 Oct 2024 06:32:23 +0000 Subject: [PATCH 11/12] Update directory --- DIRECTORY.md | 1 - 1 file changed, 1 deletion(-) diff --git a/DIRECTORY.md b/DIRECTORY.md index 425cde745473..0fd1ebe62897 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -971,7 +971,6 @@ * [BreadthFirstSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/BreadthFirstSearchTest.java) * [DepthFirstSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/DepthFirstSearchTest.java) * [ExponentialSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/ExponentialSearchTest.java) - * [FibonacciSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/FibonacciSearchTest.java) * [HowManyTimesRotatedTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/HowManyTimesRotatedTest.java) * [KMPSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/KMPSearchTest.java) * [OrderAgnosticBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/OrderAgnosticBinarySearchTest.java) From 26b40010628510a2048708b6be5bcb74177ce025 Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Wed, 9 Oct 2024 12:03:09 +0530 Subject: [PATCH 12/12] Fix --- .../java/com/thealgorithms/searches/FibonacciSearch.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/com/thealgorithms/searches/FibonacciSearch.java b/src/main/java/com/thealgorithms/searches/FibonacciSearch.java index 1f645638835a..028ab07e0a86 100644 --- a/src/main/java/com/thealgorithms/searches/FibonacciSearch.java +++ b/src/main/java/com/thealgorithms/searches/FibonacciSearch.java @@ -24,14 +24,18 @@ public > int find(T[] array, T key) { int fibMinus2 = 0; int fibNumber = fibMinus1 + fibMinus2; int n = array.length; + while (fibNumber < n) { fibMinus2 = fibMinus1; fibMinus1 = fibNumber; fibNumber = fibMinus2 + fibMinus1; } + int offset = -1; + while (fibNumber > 1) { int i = Math.min(offset + fibMinus2, n - 1); + if (array[i].compareTo(key) < 0) { fibNumber = fibMinus1; fibMinus1 = fibMinus2; @@ -45,9 +49,11 @@ public > int find(T[] array, T key) { return i; } } + if (fibMinus1 == 1 && array[offset + 1] == key) { return offset + 1; } + return -1; }