简体   繁体   中英

Replace Strings with specific list of words

Replace a given string at given index with list of words. The problem statement goes below, can someone give me some intuition or idea how to proceed on this?

//A replacement class similar to Linked List
class Replacement {
        int start;
        String before;
        String after;

    //Method to replace the words
    public static String replaceRanges(String text, List<Replacement> replacements) {
        //TODO your code here
        return null;
    }

}

/* below is the example of the problem
    Example #1:
    Input: 
    text = "num foo"
    replacements = [
    {start: 0, before: "num", after: "String"},
    {start: 4, before: "foo", after: "bar"}
    ]
    Output:
    replaceRanges(text, replacements) returns:
    "String bar"
    Example #2: Input: text = "num_fooBar", Output: "String_barBar"
*/

If you have your replacements sorted from smallest index to highest, you can iterate the list from last to first and search for substrings in input string and replace them if they match

public static String replaceRanges(String text, List<Replacement> replacements) {
    StringBuilder s = new StringBuilder(text);

    for (int i = replacements.size() - 1; i>=0; i--) {
        Replacement r = replacements.get(i);
        int begin = r.start;
        int end = r.start + r.before.length();
        if (begin >= 0 && begin < s.length() && end >= 0 && end <= s.length()) {
            if (s.substring(begin, end).equals(r.before)) {
                s.replace(begin, end, r.after);
            }
        }
    }

    return s.toString();
}

If your list is not sorted, you need to sort it first using Collections.sort() .

I used this code for testing:

public static void main(String[] args) {
    List<Replacement> replacements = List.of(
            new Replacement(0, "num", "String"), 
            new Replacement(4, "foo", "bar"));

    System.out.println(replaceRanges("num foo", replacements)); // Output: String bar
    System.out.println(replaceRanges("num_fooBar", replacements)); // Output: String_barBar
    System.out.println(replaceRanges("num_f", replacements)); // Output: String_f
    System.out.println(replaceRanges("", replacements)); // Output: 
    System.out.println(replaceRanges("foonum", replacements)); // Output: foonum
}

You could replace your original string one by one and keep in mind that you have to shift the start position (because you could replace the small substring to the bigger substring)

public String replaceRanges(String text, List<Replacement> replacements) {
    for(int i = 0; i < replacements.size(); i++) {
        Replacement replacement = replacements.get(i);
        String firstPart = text.substring(0, replacement.start);
        String secondPart = text.substring(replacement.start, text.length());
        String updatedSecondPart = secondPart.replace(replacement.before, replacement.after);
        text = firstPart + updatedSecondPart;
        updateStart(i + 1, replacements, updatedSecondPart.length() - secondPart.length());
    }
    return text;
}

privat void updateStart(int startIndex, List<Replacement> replacements, int shift) {
    for( int i = startIndex; i < replacements.size(); i++) {
        Replacement r = replacements.get(i);
        r.start += shift;
    }
}

Using this method you can process:

Replacement r1 = new Replacement(0, "hi", "Hello");
Replacement r2 = new Replacement(2, "lo", "p");
Sting result = replaceRanges("hi louie!", asList(r1, r2)); //result = 'Hello puie!'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM