refactor: BoyerMoore (#5395)

This commit is contained in:
Alex Klymenko 2024-08-26 09:33:24 +02:00 committed by GitHub
parent 5f6510f0fa
commit 35f23d2ddc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 53 additions and 26 deletions

View File

@ -1,54 +1,81 @@
/* this Code is the illustration of Boyer moore's voting algorithm to
find the majority element is an array that appears more than n/2 times in an array
where "n" is the length of the array.
For more information on the algorithm refer
https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_majority_vote_algorithm
*/
package com.thealgorithms.others; package com.thealgorithms.others;
import java.util.Optional; import java.util.Optional;
/**
* Utility class implementing Boyer-Moore's Voting Algorithm to find the majority element
* in an array. The majority element is defined as the element that appears more than n/2 times
* in the array, where n is the length of the array.
*
* For more information on the algorithm, refer to:
* https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_majority_vote_algorithm
*/
public final class BoyerMoore { public final class BoyerMoore {
private BoyerMoore() { private BoyerMoore() {
} }
public static Optional<Integer> findMajor(final int[] a) { /**
final var candidate = findCandidate(a); * Finds the majority element in the given array if it exists.
final var count = countOccurrences(candidate, a); *
if (isMajority(count, a.length)) { * @param array the input array
* @return an Optional containing the majority element if it exists, otherwise an empty Optional
*/
public static Optional<Integer> findMajorityElement(int[] array) {
if (array == null || array.length == 0) {
return Optional.empty();
}
int candidate = findCandidate(array);
int count = countOccurrences(candidate, array);
if (isMajority(count, array.length)) {
return Optional.of(candidate); return Optional.of(candidate);
} }
return Optional.empty(); return Optional.empty();
} }
private static int findCandidate(final int[] a) { /**
* Identifies the potential majority candidate using Boyer-Moore's Voting Algorithm.
*
* @param array the input array
* @return the candidate for the majority element
*/
private static int findCandidate(final int[] array) {
int count = 0; int count = 0;
int candidate = -1; int candidate = -1;
for (final var k : a) { for (int value : array) {
if (count == 0) { if (count == 0) {
candidate = k; candidate = value;
count = 1;
} else {
if (k == candidate) {
count++;
} else {
count--;
}
} }
count += (value == candidate) ? 1 : -1;
} }
return candidate; return candidate;
} }
private static int countOccurrences(final int candidate, final int[] a) { /**
* Counts the occurrences of the candidate element in the array.
*
* @param candidate the candidate element
* @param array the input array
* @return the number of times the candidate appears in the array
*/
private static int countOccurrences(final int candidate, final int[] array) {
int count = 0; int count = 0;
for (final var j : a) { for (int value : array) {
if (j == candidate) { if (value == candidate) {
count++; count++;
} }
} }
return count; return count;
} }
private static boolean isMajority(final int count, final int totalCount) { /**
* Determines if the count of the candidate element is more than n/2, where n is the length of the array.
*
* @param count the number of occurrences of the candidate
* @param totalCount the total number of elements in the array
* @return true if the candidate is the majority element, false otherwise
*/
private static boolean isMajority(int count, int totalCount) {
return 2 * count > totalCount; return 2 * count > totalCount;
} }
} }

View File

@ -11,7 +11,7 @@ public class BoyerMooreTest {
@ParameterizedTest @ParameterizedTest
@MethodSource("inputStreamWithExistingMajority") @MethodSource("inputStreamWithExistingMajority")
void checkWhenMajorityExists(int expected, int[] input) { void checkWhenMajorityExists(int expected, int[] input) {
Assertions.assertEquals(expected, BoyerMoore.findMajor(input).get()); Assertions.assertEquals(expected, BoyerMoore.findMajorityElement(input).get());
} }
private static Stream<Arguments> inputStreamWithExistingMajority() { private static Stream<Arguments> inputStreamWithExistingMajority() {
@ -21,7 +21,7 @@ public class BoyerMooreTest {
@ParameterizedTest @ParameterizedTest
@MethodSource("inputStreamWithoutMajority") @MethodSource("inputStreamWithoutMajority")
void checkWhenMajorityExists(int[] input) { void checkWhenMajorityExists(int[] input) {
Assertions.assertFalse(BoyerMoore.findMajor(input).isPresent()); Assertions.assertFalse(BoyerMoore.findMajorityElement(input).isPresent());
} }
private static Stream<Arguments> inputStreamWithoutMajority() { private static Stream<Arguments> inputStreamWithoutMajority() {