LintCode 841: String Replace (字符串替换好题)

  1. String Replace

Given two identical-sized string array A, B and a string S. All substrings A appearing in S are replaced by B.(Notice: From left to right, it must be replaced if it can be replaced. If there are multiple alternatives, replace longer priorities. After the replacement of the characters can’t be replaced again.)

Example
Example 1

Input:
A = [“ab”,“aba”]
B = [“cc”,“ccc”]
S = “ababa”

Output: “cccba”
Explanation: In accordance with the rules, the substring that can be replaced is “ab” or “aba”. Since “aba” is longer, we replace “aba” with “ccc”.
Example 2

Input:
A = [“ab”,“aba”]
B = [“cc”,“ccc”]
S = “aaaaa”

Output: “aaaaa”
Explanation: S does not contain strings in A, so no replacement is done.
Example 3

Input:
A = [“cd”,“dab”,“ab”]
B = [“cc”,“aaa”,“dd”]
S = “cdab”

Output: “ccdd”
Explanation: From left to right, you can find the “cd” can be replaced at first, so after the replacement becomes “ccab”, then you can find “ab” can be replaced, so the string after the replacement is “ccdd”.
Notice
The size of each string array does not exceed 100, the total string length does not exceed 50000.
The lengths of A [i] and B [i] are equal.
The length of S does not exceed 50000.
All characters are lowercase letters.
We guarantee that the A array does not have the same string

解法1:
思路:基于hashmap。把a[i]和b[i]map起来。

  1. 先对a[]按字符串长短排序。
  2. 维护pos, 遍历a[],看a[i]是否为S的substr(pos, a[i].size())。如是,则将a[1]替换成b[i]。
    注意:
    1)一定要对a[]排序,遍历a[],看其是否在S中。我开始的想法是不用排序,用两个指针的办法遍历S,看能不能找到S[p1…p2]是不是在a[]中,如果找到,再看S[p1…p2++]是不是也在a[]中。一直到找不到了再替换。但这个贪婪算法是有问题的。比如说
    Input:
    A = [“ab”,“aba”, “badd”]
    B = [“cc”,“ccc”, “cccc”]
    S = “abadd”
    对于第一个匹配字符串,该算法先找到ab是匹配,然后再发现aba也是,然后abad不在a[]中了,则将aba替换成ccc,此时S=“cccdd”。但是实际上第一个应该替换的字符串是badd,即S=“acccc”。
  3. pos += len - 1; 这里记得-1,因为下面还有pos++;
  4. 我开始没有用substring = substr(),而是直接用s.find(a[i])。但该方法超时,因为find()要遍历整个s,很慢。

代码如下:

struct compare {
    bool operator() (string & a, string & b) {
        return a.size() > b.size();
    }
} cmp;

class Solution {
public:
    /**
     * @param a: The A array
     * @param b: The B array
     * @param s: The S string
     * @return: The answer
     */
    string stringReplace(vector<string> &a, vector<string> &b, string &s) {
        int M = a.size();
        int N = b.size();
        int K = s.size();
        if (M != N || M == 0 || K == 0) return s;
        
        unordered_map<string, string> um;
        
        for (int i = 0; i < M; ++i) {
            um[a[i]] = b[i];
        }
        
        sort(a.begin(), a.end(), cmp);
        
        int index = 0; //index in a[]
        int pos = 0;
    
        while(pos < K) {
            for (int i = 0; i < M; ++i) {
                int len = a[i].size();
                if (pos + len > K) continue;
                string subString = s.substr(pos, len);
                //if (s.find(a[i]) == pos) {   //consume too much time!!!
                if (subString == a[i]) {
                    s.replace(pos, len, um[s.substr(pos, len)]);
                    pos += len - 1; //remember to -1 as it will pos++ below
                    break;
                }
            }
            pos++;
        }
        
        return s;
    }
};

解法2:滚动Hash (Rabin Karp 算法)。
TBD。

代码同步在
https://github.com/luqian2017/Algorithm

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值