字符串相关算法/KMP/LCS(个人留档)

KMP字符串匹配

int *getnext(string s2)
{
    int len = s2.size();
    int *next = new int[len];
    next[0] = -1;
    int j = 0, k = -1;
    while (j < len)
    {
        if (k == -1 || s2[j] == s2[k])
        {
            j++;
            k++;
            next[j] = k;
        }
        else
        {
            k = next[k];
        }
    }
    return next;
}

void kmpsearch(string s1, string s2)
{
    int *next = getnext(s2);
    int i = 0, j = 0;
    int len1 = s1.size();
    int len2 = s2.size();
    for (int i = 0, j = 0; i < len1;)
    {
        while (i < len1 && j < len2)
        {
            if (j == -1 || s1[i] == s2[j])
            {
                i++, j++;
            }
            else
                j = next[j];
        }
        if (j == len2)
        {
            ans.push_back(i - len2);
            i -= len2 - 1;
            j = 0;
        }
    }
    return;
}

LCS最长公共子串

int LCS(string s, string t)
{
    int lens = s.size();
    int lent = t.size();
    int dp[lens + 1][lent + 1];
    int B[lens + 1][lent + 1]; //0,1上,2左
    for (int i = 0; i < lens + 1; i++)
        dp[i][0] = 0;
    for (int j = 0; j < lent + 1; j++)
        dp[0][j] = 0;
    for (int i = 1; i <= lens; i++)
    {
        for (int j = 1; j <= lent; j++)
        {
            if (s[i - 1] == t[j - 1])
            {
                dp[i][j] = dp[i - 1][j - 1] + 1;
                B[i][j] = 0;
            }
            else
            {
                if (dp[i - 1][j] > dp[i][j - 1])
                {
                    dp[i][j] = dp[i - 1][j];
                    B[i][j] = 1;
                }
                else
                {
                    dp[i][j] = dp[i][j - 1];
                    B[i][j] = 2;
                }
            }
        }
    }

    int i = lens, j = lent;
    vector<char> output;
    do
    {
        while (i >= 0 && j >= 0 && (B[i][j] == 1 || B[i][j] == 2))
        {
            if (B[i][j] == 1)
                i--;
            else
                j--;
        }
        if (B[i][j] == 0)
        {
            output.emplace_back(s[i - 1]);
            i--, j--;
        }
    } while (i >= 1 && j >= 1);
    for (int i = output.size() - 1; i >= 0; i--)
        cout << output[i];

    return dp[lens][lent];
}

前缀树

//leetcode208
class Trie
{
private:
    vector<Trie *> children;
    bool isEnd;

    Trie *searchprefix(string word)
    {
        Trie *node = this;
        for (char ch : word)
        {
            int c = ch - 'a';
            if (!node->children[c])
                return nullptr;
            node = node->children[c];
        }
        return node;
    }

public:
    /** Initialize your data structure here. */
    Trie() : children(26), isEnd(false){};

    /** Inserts a word into the trie. */
    void insert(string word)
    {
        Trie *node = this;
        for (char ch : word)
        {
            int c = ch - 'a';
            if (!node->children[c])
                node->children[c] = new Trie();
            node = node->children[c];
        }
        node->isEnd = true;
        return;
    }

    /** Returns if the word is in the trie. */
    bool search(string word)
    {
        Trie *node = searchprefix(word);
        if (node == nullptr)
            return false;
        return node->isEnd;
    }

    /** Returns if there is any word in the trie that starts with the given prefix. */
    bool startsWith(string prefix)
    {
        Trie *node = searchprefix(prefix);
        if (node == nullptr || node->children.size() == 0)
            return false;
        return true;
    }
};

/**
 * Your Trie object will be instantiated and called as such:
 * Trie* obj = new Trie();
 * obj->insert(word);
 * bool param_2 = obj->search(word);
 * bool param_3 = obj->startsWith(prefix);
 */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值