Repository: TheAlgorithms/Java
Pull request #5701 (2024-10-10 14:07:28)

feat: Add `RandomSearch` new algorithm with Junit tests
<!--
Thank you for your contribution!
In order to reduce the number of notifications sent to the maintainers, please:
- create your PR as draft, cf. https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests#draft-pull-requests,
- make sure that all of the CI checks pass,
- mark your PR as ready for review, cf. https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/changing-the-stage-of-a-pull-request#marking-a-pull-request-as-ready-for-review
-->

<!-- For completed items, change [ ] to [x] -->

- [x] I have read [CONTRIBUTING.md](https://github.com/TheAlgorithms/Java/blob/master/CONTRIBUTING.md).
- [x] This pull request is all my own work -- I have not plagiarized it.
- [x] All filenames are in PascalCase.
- [x] All functions and variable names follow Java naming conventions.
- [x] All new algorithms have a URL in their comments that points to Wikipedia or other similar explanations.
- [x] All new code is formatted with `clang-format -i --style=file path/to/your/file.java`

codecov-commenter: ## [Codecov](https://app.codecov.io/gh/TheAlgorithms/Java/pull/5701?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TheAlgorithms) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 59.74%. Comparing base [(`90d20b3`)](https://app.codecov.io/gh/TheAlgorithms/Java/commit/90d20b3a43642548ecc55e425517583080a81e2a?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TheAlgorithms) to head [(`6715842`)](https://app.codecov.io/gh/TheAlgorithms/Java/commit/6715842ac394c45e6e74042e1df0bd26a16f8038?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TheAlgorithms).

<details><summary>Additional details and impacted files</summary>


```diff
@@             Coverage Diff              @@
##             master    #5701      +/-   ##
============================================
+ Coverage     59.71%   59.74%   +0.02%     
- Complexity     3855     3859       +4     
============================================
  Files           561      562       +1     
  Lines         16017    16028      +11     
  Branches       3073     3075       +2     
============================================
+ Hits           9565     9576      +11     
  Misses         6047     6047              
  Partials        405      405              
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/TheAlgorithms/Java/pull/5701?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TheAlgorithms).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TheAlgorithms).


Patch:
diff --git a/DIRECTORY.md b/DIRECTORY.md
index e022ddc2..d0f50b42 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -56,6 +56,7 @@
             * [Caesar](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/Caesar.java)
             * [ColumnarTranspositionCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/ColumnarTranspositionCipher.java)
             * [DES](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/DES.java)
+            * [ECC](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/ECC.java)
             * [HillCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/HillCipher.java)
             * [PlayfairCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/PlayfairCipher.java)
             * [Polybius](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/Polybius.java)
@@ -275,6 +276,7 @@
             * [ShortestCommonSupersequenceLength](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/ShortestCommonSupersequenceLength.java)
             * [SubsetCount](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/SubsetCount.java)
             * [SubsetSum](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/SubsetSum.java)
+            * [SubsetSumSpaceOptimized](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/SubsetSumSpaceOptimized.java)
             * [SumOfSubset](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/SumOfSubset.java)
             * [Tribonacci](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/Tribonacci.java)
             * [UniquePaths](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/UniquePaths.java)
@@ -396,6 +398,7 @@
             * [SecondMinMax](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SecondMinMax.java)
             * [SieveOfEratosthenes](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SieveOfEratosthenes.java)
             * [SimpsonIntegration](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SimpsonIntegration.java)
+            * [SolovayStrassenPrimalityTest](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SolovayStrassenPrimalityTest.java)
             * [SquareFreeInteger](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SquareFreeInteger.java)
             * [SquareRootWithBabylonianMethod](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SquareRootWithBabylonianMethod.java)
             * [SquareRootWithNewtonRaphsonMethod](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SquareRootWithNewtonRaphsonMethod.java)
@@ -511,6 +514,7 @@
             * [PerfectBinarySearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/PerfectBinarySearch.java)
             * [QuickSelect](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/QuickSelect.java)
             * [RabinKarpAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/RabinKarpAlgorithm.java)
+            * [RandomSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/RandomSearch.java)
             * [RecursiveBinarySearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/RecursiveBinarySearch.java)
             * [RowColumnWiseSorted2dArrayBinarySearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearch.java)
             * [SaddlebackSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/SaddlebackSearch.java)
@@ -664,12 +668,13 @@
               * [LFSRTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/a5/LFSRTest.java)
             * [AESEncryptionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/AESEncryptionTest.java)
             * [AffineCipherTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/AffineCipherTest.java)
-            * [AtbashTest](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/AtbashTest.java)
+            * [AtbashTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/AtbashTest.java)
             * [AutokeyTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/AutokeyTest.java)
             * [BlowfishTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/BlowfishTest.java)
             * [CaesarTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/CaesarTest.java)
             * [ColumnarTranspositionCipherTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/ColumnarTranspositionCipherTest.java)
             * [DESTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/DESTest.java)
+            * [ECCTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/ECCTest.java)
             * [HillCipherTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/HillCipherTest.java)
             * [PlayfairTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/PlayfairTest.java)
             * [PolybiusTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/PolybiusTest.java)
@@ -829,6 +834,7 @@
             * [RodCuttingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/RodCuttingTest.java)
             * [ShortestCommonSupersequenceLengthTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/ShortestCommonSupersequenceLengthTest.java)
             * [SubsetCountTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/SubsetCountTest.java)
+            * [SubsetSumSpaceOptimizedTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/SubsetSumSpaceOptimizedTest.java)
             * [SubsetSumTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/SubsetSumTest.java)
             * [SumOfSubsetTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/SumOfSubsetTest.java)
             * [TribonacciTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/TribonacciTest.java)
@@ -935,6 +941,7 @@
             * [ReverseNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/ReverseNumberTest.java)
             * [SecondMinMaxTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/SecondMinMaxTest.java)
             * [SieveOfEratosthenesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/SieveOfEratosthenesTest.java)
+            * [SolovayStrassenPrimalityTestTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/SolovayStrassenPrimalityTestTest.java)
             * [SquareFreeIntegerTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/SquareFreeIntegerTest.java)
             * [SquareRootwithBabylonianMethodTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/SquareRootwithBabylonianMethodTest.java)
             * [SquareRootWithNewtonRaphsonTestMethod](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/SquareRootWithNewtonRaphsonTestMethod.java)
@@ -1018,6 +1025,7 @@
             * [PerfectBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/PerfectBinarySearchTest.java)
             * [QuickSelectTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/QuickSelectTest.java)
             * [RabinKarpAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/RabinKarpAlgorithmTest.java)
+            * [RandomSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/RandomSearchTest.java)
             * [RecursiveBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/RecursiveBinarySearchTest.java)
             * [RowColumnWiseSorted2dArrayBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearchTest.java)
             * [SaddlebackSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/SaddlebackSearchTest.java)
diff --git a/src/main/java/com/thealgorithms/searches/RandomSearch.java b/src/main/java/com/thealgorithms/searches/RandomSearch.java
new file mode 100644
index 00000000..3417ff7d
--- /dev/null
+++ b/src/main/java/com/thealgorithms/searches/RandomSearch.java
@@ -0,0 +1,45 @@
+package com.thealgorithms.searches;
+
+import com.thealgorithms.devutils.searches.SearchAlgorithm;
+import java.util.HashSet;
+import java.util.Random;
+import java.util.Set;
+
+/**
+ * A Random Search algorithm that randomly selects an index and checks if the
+ * value at that index matches the target. It repeats the process until it
+ * finds the target or checks all elements.
+ *
+ * <p>
+ * Time Complexity: O(n) in the worst case.
+ * </p>
+ *
+ * @author Hardvan
+ */
+public class RandomSearch implements SearchAlgorithm {
+
+    private final Random random = new Random();
+
+    /**
+     * Finds the index of a given element using random search.
+     *
+     * @param array Array to search through
+     * @param key Element to search for
+     * @return Index of the element if found, -1 otherwise
+     */
+    @Override
+    public <T extends Comparable<T>> int find(T[] array, T key) {
+        Set<Integer> visitedIndices = new HashSet<>();
+        int size = array.length;
+
+        while (visitedIndices.size() < size) {
+            int randomIndex = random.nextInt(size);
+            if (array[randomIndex].compareTo(key) == 0) {
+                return randomIndex;
+            }
+            visitedIndices.add(randomIndex);
+        }
+
+        return -1;
+    }
+}


Test patch:
diff --git a/src/test/java/com/thealgorithms/searches/RandomSearchTest.java b/src/test/java/com/thealgorithms/searches/RandomSearchTest.java
new file mode 100644
index 00000000..0a1dbeaf
--- /dev/null
+++ b/src/test/java/com/thealgorithms/searches/RandomSearchTest.java
@@ -0,0 +1,87 @@
+package com.thealgorithms.searches;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+class RandomSearchTest {
+
+    private RandomSearch randomSearch;
+
+    @BeforeEach
+    void setUp() {
+        randomSearch = new RandomSearch();
+    }
+
+    @Test
+    void testElementFound() {
+        Integer[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+        Integer key = 5;
+        int index = randomSearch.find(array, key);
+
+        assertNotEquals(-1, index, "Element should be found in the array.");
+        assertEquals(key, array[index], "Element found should match the key.");
+    }
+
+    @Test
+    void testElementNotFound() {
+        Integer[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+        Integer key = 11;
+        int index = randomSearch.find(array, key);
+
+        assertEquals(-1, index, "Element not present in the array should return -1.");
+    }
+
+    @Test
+    void testEmptyArray() {
+        Integer[] emptyArray = {};
+        Integer key = 5;
+        int index = randomSearch.find(emptyArray, key);
+
+        assertEquals(-1, index, "Searching in an empty array should return -1.");
+    }
+
+    @Test
+    void testSingleElementArrayFound() {
+        Integer[] array = {5};
+        Integer key = 5;
+        int index = randomSearch.find(array, key);
+
+        assertEquals(0, index, "The key should be found at index 0 in a single-element array.");
+    }
+
+    @Test
+    void testSingleElementArrayNotFound() {
+        Integer[] array = {1};
+        Integer key = 5;
+        int index = randomSearch.find(array, key);
+
+        assertEquals(-1, index, "The key should not be found in a single-element array if it does not match.");
+    }
+
+    @Test
+    void testDuplicateElementsFound() {
+        Integer[] array = {1, 2, 3, 4, 5, 5, 5, 7, 8, 9, 10};
+        Integer key = 5;
+        int index = randomSearch.find(array, key);
+
+        assertNotEquals(-1, index, "The key should be found in the array with duplicates.");
+        assertEquals(key, array[index], "The key found should be 5.");
+    }
+
+    @Test
+    void testLargeArray() {
+        Integer[] largeArray = new Integer[1000];
+        for (int i = 0; i < largeArray.length; i++) {
+            largeArray[i] = i + 1; // Fill with values 1 to 1000
+        }
+
+        Integer key = 500;
+        int index = randomSearch.find(largeArray, key);
+
+        assertNotEquals(-1, index, "The key should be found in the large array.");
+        assertEquals(key, largeArray[index], "The key found should match 500.");
+    }
+}