RemoveLeftmostSubstring

public class RemoveLeftmostSubstring {
    public static String removeLeftmostSubstring(String input, String target) {
        while (true) {
            int index = input.indexOf(target);
            if (index == -1) {
                break;
            }
            input = input.substring(0, index) + input.substring(index + target.length());
        }
        return input;
    }

}
import org.junit.Test;
import static org.junit.Assert.*;

/**
 * Comprehensive tests for removeLeftmostSubstring.
 * The method removes the leftmost occurrence of target repeatedly
 * until no occurrence remains.
 */
public class RemoveLeftmostSubstringTest {

    // 被测方法(使用 String 的方法实现)
    private static String removeLeftmostSubstring(String input, String target) {
        if (input == null) return null;
        if (target == null || target.length() == 0) return input; // 约定:空目标不修改字符串
        String s = input;
        while (true) {
            int idx = s.indexOf(target);
            if (idx == -1) break;
            s = s.substring(0, idx) + s.substring(idx + target.length());
        }
        return s;
    }

    // 0 次移除(目标子字符串不存在)
    @Test
    public void testZeroRemovals() {
        String input = "hello world";
        String target = "xyz";
        String expectedOutput = "hello world";
        assertEquals("Should return the original string when no match is found",
                expectedOutput, removeLeftmostSubstring(input, target));
    }

    // 1 次移除(目标子字符串只出现一次)
    @Test
    public void testOneRemoval() {
        String input = "hello world";
        String target = "hello";
        String expectedOutput = " world";
        assertEquals("Should remove the target substring when it appears once",
                expectedOutput, removeLeftmostSubstring(input, target));
    }

    // 2 次移除(目标子字符串出现两次 -> 两次都被移除)
    @Test
    public void testTwoRemovals() {
        String input = "hello world hello";
        String target = "hello";
        String expectedOutput = " world "; // 两次移除后中间与尾部空格都会保留
        assertEquals("Should remove all leftmost occurrences until none remain",
                expectedOutput, removeLeftmostSubstring(input, target));
    }

    // 多次移除(目标子字符串出现多次)
    @Test
    public void testMultipleRemovals() {
        String input = "abcabcabc";
        String target = "abc";
        String expectedOutput = "";
        assertEquals("Should remove all occurrences until no match is found",
                expectedOutput, removeLeftmostSubstring(input, target));
    }

    // 移除后引入新的目标子字符串(移除可能拼接出新的目标)
    @Test
    public void testRemovalIntroducesTarget() {
        String input = "xxxxyxxxxyxxx";
        String target = "xyx";
        // 逐步移除后最终结果为 7 个 'x'
        String expectedOutput = "xxxxxxx";
        assertEquals("Should handle cases where removal introduces the target substring",
                expectedOutput, removeLeftmostSubstring(input, target));
    }

    // 空输入字符串
    @Test
    public void testEmptyInputString() {
        String input = "";
        String target = "abc";
        String expectedOutput = "";
        assertEquals("Should return an empty string when the input is empty",
                expectedOutput, removeLeftmostSubstring(input, target));
    }

    // 空目标子字符串(约定:不做任何移除)
    @Test
    public void testEmptyTargetString() {
        String input = "hello world";
        String target = "";
        String expectedOutput = "hello world";
        assertEquals("Should return the original string when the target is an empty string",
                expectedOutput, removeLeftmostSubstring(input, target));
    }

    // 目标子字符串比输入字符串长
    @Test
    public void testTargetLongerThanInput() {
        String input = "abc";
        String target = "abcd";
        String expectedOutput = "abc";
        assertEquals("Should return the original string when the target is longer than the input",
                expectedOutput, removeLeftmostSubstring(input, target));
    }

    // 输入字符串包含特殊字符
    @Test
    public void testInputWithSpecialCharacters() {
        String input = "hello @world! #test";
        String target = "@world!";
        String expectedOutput = "hello  #test";
        assertEquals("Should handle input strings with special characters",
                expectedOutput, removeLeftmostSubstring(input, target));
    }

    // 目标子字符串包含特殊字符并出现多次
    @Test
    public void testTargetWithSpecialCharacters() {
        String input = "hello @world! #test @world!";
        String target = "@world!";
        String expectedOutput = "hello  #test ";
        assertEquals("Should handle target substrings with special characters",
                expectedOutput, removeLeftmostSubstring(input, target));
    }

    // 目标子字符串是输入字符串的前缀(并可能被多次移除)
    @Test
    public void testTargetAsPrefix() {
        String input = "hellohello world";
        String target = "hello";
        String expectedOutput = " world";
        assertEquals("Should remove the target repeatedly when it appears as prefix(s)",
                expectedOutput, removeLeftmostSubstring(input, target));
    }

    // 目标子字符串是输入字符串的后缀(并可能被多次移除)
    @Test
    public void testTargetAsSuffix() {
        String input = "hello worldhello";
        String target = "hello";
        String expectedOutput = " world";
        assertEquals("Should remove the target repeatedly when it appears as suffix(s)",
                expectedOutput, removeLeftmostSubstring(input, target));
    }

    // 目标子字符串重复多次且密集(重叠/接近的情况)
    @Test
    public void testDenseRepeatedTargets() {
        String input = "abababab";
        String target = "aba";
        // 解释:第一次移除 "aba" -> "babab"; 再次移除最左侧 "aba"(现在从 index1)-> "bb"
        String expectedOutput = "bb";
        assertEquals("Should handle densely repeated or overlapping targets",
                expectedOutput, removeLeftmostSubstring(input, target));
    }

    // 输入字符串与目标子字符串相同
    @Test
    public void testInputEqualsTarget() {
        String input = "hello";
        String target = "hello";
        String expectedOutput = "";
        assertEquals("Should remove the entire string when input equals target",
                expectedOutput, removeLeftmostSubstring(input, target));
    }

    // 额外:null 输入的行为(合理性测试)
    @Test
    public void testNullInput() {
        String input = null;
        String target = "a";
        assertNull("If input is null, should return null", removeLeftmostSubstring(input, target));
    }
}
posted @ 2025-10-16 22:30  ji415  阅读(11)  评论(1)    收藏  举报