diff --git a/src/main/java/com/thealgorithms/others/BoyerMoore.java b/src/main/java/com/thealgorithms/others/BoyerMoore.java index d9d5b5d02..e67427ded 100644 --- a/src/main/java/com/thealgorithms/others/BoyerMoore.java +++ b/src/main/java/com/thealgorithms/others/BoyerMoore.java @@ -5,35 +5,50 @@ For more information on the algorithm refer https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_majority_vote_algorithm */ package com.thealgorithms.others; +import java.util.Optional; public final class BoyerMoore { private BoyerMoore() { } - public static int findmajor(final int[] a) { + public static Optional findMajor(final int[] a) { + final var candidate = findCandidate(a); + final var count = countOccurrences(candidate, a); + if (isMajority(count, a.length)) { + return Optional.of(candidate); + } + return Optional.empty(); + } + + private static int findCandidate(final int[] a) { int count = 0; - int cand = -1; + int candidate = -1; for (final var k : a) { if (count == 0) { - cand = k; + candidate = k; count = 1; } else { - if (k == cand) { + if (k == candidate) { count++; } else { count--; } } } - count = 0; + return candidate; + } + + private static int countOccurrences(final int candidate, final int[] a) { + int count = 0; for (final var j : a) { - if (j == cand) { + if (j == candidate) { count++; } } - if (count > (a.length / 2)) { - return cand; - } - return -1; + return count; + } + + private static boolean isMajority(final int count, final int totalCount) { + return 2 * count > totalCount; } } diff --git a/src/test/java/com/thealgorithms/others/BoyerMooreTest.java b/src/test/java/com/thealgorithms/others/BoyerMooreTest.java index b614c1407..b1497f7bc 100644 --- a/src/test/java/com/thealgorithms/others/BoyerMooreTest.java +++ b/src/test/java/com/thealgorithms/others/BoyerMooreTest.java @@ -11,12 +11,22 @@ import org.junit.jupiter.params.provider.MethodSource; public class BoyerMooreTest { @ParameterizedTest - @MethodSource("inputStream") - void numberTests(int expected, int[] input) { - Assertions.assertEquals(expected, BoyerMoore.findmajor(input)); + @MethodSource("inputStreamWithExistingMajority") + void checkWhenMajorityExists(int expected, int[] input) { + Assertions.assertEquals(expected, BoyerMoore.findMajor(input).get()); } - private static Stream inputStream() { - return Stream.of(Arguments.of(5, new int[] {5, 5, 5, 2}), Arguments.of(10, new int[] {10, 10, 20}), Arguments.of(10, new int[] {10, 20, 10}), Arguments.of(10, new int[] {20, 10, 10}), Arguments.of(-1, new int[] {10, 10, 20, 20, 30, 30}), Arguments.of(4, new int[] {1, 4, 2, 4, 4, 5, 4})); + private static Stream inputStreamWithExistingMajority() { + return Stream.of(Arguments.of(5, new int[] {5, 5, 5, 2}), Arguments.of(10, new int[] {10, 10, 20}), Arguments.of(10, new int[] {10, 20, 10}), Arguments.of(10, new int[] {20, 10, 10}), Arguments.of(4, new int[] {1, 4, 2, 4, 4, 5, 4}), Arguments.of(-1, new int[] {-1})); + } + + @ParameterizedTest + @MethodSource("inputStreamWithoutMajority") + void checkWhenMajorityExists(int[] input) { + Assertions.assertFalse(BoyerMoore.findMajor(input).isPresent()); + } + + private static Stream inputStreamWithoutMajority() { + return Stream.of(Arguments.of(new int[] {10, 10, 20, 20, 30, 30}), Arguments.of(new int[] {10, 20, 30, 40, 50}), Arguments.of(new int[] {1, 2}), Arguments.of(new int[] {})); } }