Skip to content

feat: Add Abbreviation new algorithm with Junit tests #5790

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@
* [StrassenMatrixMultiplication](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplication.java)
* [TilingProblem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/divideandconquer/TilingProblem.java)
* dynamicprogramming
* [Abbreviation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/Abbreviation.java)
* [BoardPath](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/BoardPath.java)
* [BoundaryFill](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/BoundaryFill.java)
* [BruteForceKnapsack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsack.java)
Expand Down Expand Up @@ -862,6 +863,7 @@
* [StrassenMatrixMultiplicationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplicationTest.java)
* [TilingProblemTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/divideandconquer/TilingProblemTest.java)
* dynamicprogramming
* [AbbreviationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/AbbreviationTest.java)
* [BoardPathTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/BoardPathTest.java)
* [BoundaryFillTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/BoundaryFillTest.java)
* [BruteForceKnapsackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsackTest.java)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.thealgorithms.dynamicprogramming;

/**
* A class that provides a solution to the abbreviation problem.
*
* Problem: Given two strings, `a` and `b`, determine if string `a` can be
* transformed into string `b` by performing the following operations:
* 1. Capitalize zero or more of `a`'s lowercase letters (i.e., convert them to uppercase).
* 2. Delete any of the remaining lowercase letters from `a`.
*
* The task is to determine whether it is possible to make string `a` equal to string `b`.
*
* @author Hardvan
*/
public final class Abbreviation {
private Abbreviation() {
}

/**
* Determines if string `a` can be transformed into string `b` by capitalizing
* some of its lowercase letters and deleting the rest.
*
* @param a The input string which may contain both uppercase and lowercase letters.
* @param b The target string containing only uppercase letters.
* @return {@code true} if string `a` can be transformed into string `b`,
* {@code false} otherwise.
*
* Time Complexity: O(n * m) where n = length of string `a` and m = length of string `b`.
* Space Complexity: O(n * m) due to the dynamic programming table.
*/
public static boolean abbr(String a, String b) {
int n = a.length();
int m = b.length();

boolean[][] dp = new boolean[n + 1][m + 1];

dp[0][0] = true;

for (int i = 0; i < n; i++) {
for (int j = 0; j <= m; j++) {
if (dp[i][j]) {
// Case 1: If the current characters match (or can be capitalized to match)
if (j < m && Character.toUpperCase(a.charAt(i)) == b.charAt(j)) {
dp[i + 1][j + 1] = true;
}
// Case 2: If the character in `a` is lowercase, we can skip it
if (Character.isLowerCase(a.charAt(i))) {
dp[i + 1][j] = true;
}
}
}
}

return dp[n][m];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.thealgorithms.dynamicprogramming;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

public class AbbreviationTest {

@ParameterizedTest
@MethodSource("provideTestCases")
public void testAbbreviation(String a, String b, boolean expected) {
assertEquals(expected, Abbreviation.abbr(a, b));
}

private static Stream<Arguments> provideTestCases() {
return Stream.of(
// Example test case from problem description
Arguments.of("daBcd", "ABC", Boolean.TRUE),

// Test case where transformation is impossible
Arguments.of("dBcd", "ABC", Boolean.FALSE),

// Test case with exact match (all uppercase)
Arguments.of("ABC", "ABC", Boolean.TRUE),

// Test case where input string contains all required letters plus extra lowercase letters
Arguments.of("aAbBcC", "ABC", Boolean.TRUE),

// Test case with only lowercase letters in input
Arguments.of("abcd", "ABCD", Boolean.TRUE),

// Test case with an empty second string (b)
Arguments.of("abc", "", Boolean.TRUE),

// Test case with an empty first string (a) but non-empty second string (b)
Arguments.of("", "A", Boolean.FALSE),

// Complex case with interleaved letters
Arguments.of("daBcAbCd", "ABCD", Boolean.FALSE));
}
}