您的位置:首页 > 其它

寻找若干个字符串的最长公共前缀

2017-12-20 14:56 399 查看


寻找若干个字符串的最长公共前缀 Longest Common Prefix

原创 2013年10月20日
11:44:19

5502

问题:给出若干个字符串,找出他们的最长公共前缀子串。问题源于Leetcode。

假设这里字符串有n个,平均长度为m。

方法:

1、所求的最长公共前缀子串一定是每个字符串的前缀子串。所以随便选择一个字符串作为标准,把它的前缀串,与其他所有字符串进行判断,看是否是它们所有人的前缀子串。这里的时间性能是O(m*n*m)。

2、列出所有的字符串的前缀子串,将它们合并后排序,找出其中个数为n且最长的子串。时间性能为O(n*m+m*n*log(m*n))

3、纵向扫描:从下标0开始,判断每一个字符串的下标0,判断是否全部相同。直到遇到不全部相同的下标。时间性能为O(n*m)。

4、横向扫描:前两个字符串找公共子串,将其结果和第三个字符串找公共子串……直到最后一个串。时间性能为O(n*m)。

5、借助trie字典树。将这些字符串存储到trie树中。那么trie树的第一个分叉口之前的单分支树的就是所求。

代码一(方法1):

[cpp] view
plain copy

class Solution {  

public:  

    string longestCommonPrefix(vector<string> &strs) {  

        // Note: The Solution object is instantiated only once and is reused by each test case.  

        if(strs.size() == 0)  

            return "";  

        if (strs.size() ==1)  

            return strs[0];  

        string s = strs[0];  

        vector<string> spre;  

        int i;  

        for(i=1;i<=s.length();i++)  

            spre.push_back(s.substr(0, i));  

        string longest = "";  

        int flag;  

        for(int j=0; j<spre.size();j++)  

        {  

            flag = 1;  

            for(i=1;i<strs.size();i++)  

            {  

                if(!isPrefix(strs[i], spre[j]))  

                    flag = 0;  

            }  

            if(flag == 0)  

                break;  

            longest = spre[j];  

        }  

        return longest;  

    }  

  

    bool isPrefix(string m, string p)  

    {  

        int n = 0;  

        if(m.length() < p.length())  

            return false;  

        while(n<p.length())  

        {  

            if(m
 == p
)  

                n++;  

            else  

                return false;  

        }  

        return true;  

    }  

};  

代码二(方法3):纵向扫描。

[cpp] view
plain copy

class Solution {  

public:  

    string longestCommonPrefix(vector<string> &strs) {  

        if(strs.empty())  

            return "";  

        int num = strs.size();  

        int len = strs[0].size();  

        for(int i=0;i<len;i++)  

            for(int j=1;j<num;j++)  

            {  

                if(i > strs[j].size() || strs[j][i] != strs[0][i])  

                    return strs[0].substr(0, i);  

            }  

        return strs[0];  

    }  

};  

代码三(方法5):字典树。

[cpp] view
plain copy

class Solution {  

public:  

typedef struct node {   

    char ch;  

    int branch ; //记录分支树,方便最后查询  

    int times;  

    node* child[26];  

}node, *Trie;  

  

Trie init_Trie()  

{  

    Trie root = (node*)malloc(sizeof(node)); //Trie树的根节点不存储数据  

    root->branch = 0;  

    root->times = 0;  

    for(int i=0;i<26;i++)  

        root->child[i] = NULL;  

    return root;  

}  

  

void insert_Trie(Trie root, const string str)  

{  

    int n = str.length();  

    if(n == 0)  

    {  

        root->times ++;  

        return;  

    }  

    int i=0;  

    int idx;  

    node *p = root;  

    root->times++;  

    while(i<n)  

    {  

        idx = str[i] - 'a';  

        if(p->child[idx] != NULL)  

        {  

            p = p->child[idx];  

            p->times ++;  

            i++;  

        }  

        else  

        {  

            node* tmp = (node*)malloc(sizeof(node));  

            tmp->ch = str[i];  

            tmp->branch = 0;  

            tmp->times = 1;  

            for(int j=0;j<26;j++)  

                tmp->child[j] = NULL;  

  

            p->branch ++;  

            p->child[idx] = tmp;  

            p = tmp;  

            i++;  

        }  

    }  

}  

  

string longestCommonPrefix(vector<string> &strs)  

{  

    int n = strs.size();  

    if(n == 0)  

        return "";  

  

    int i;  

    Trie root = init_Trie();  

    for(i=0;i<n;i++)  

        insert_Trie(root, strs[i]);  

  

    i = 0;  

    node* p = root;  

    while(i<strs[0].length() && p->branch == 1 && p->times == n)  

    {  

        p = p->child[strs[0][i] - 'a'];  

        i++;  

    }  

    if(p->times < n)  

        i--;  

    return strs[0].substr(0,i);  

}  

      

};  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: