zoukankan      html  css  js  c++  java
  • 最长重复子串问题

      今天面试被一道没见过的题,完全整闷了。求一段字符串的最长重复子串。后来网上看看博客,竟然可以用KMP写,为自己的无知感到羞愧。好吧,我来学习一下如何用KMP方法解决这样的问题,关键是next的特性来解决这个问题。

    #include <iostream>
    #include <cstring>
    using namespace std;
    int Get_next(char *p, int nextval[])
    {
        int j = -1;
        nextval[0] = -1;
        int len = strlen(p);
        int i = 0;
        int maxlen = 0;
        while(i < len)
        {
            if(j == -1 || p[i] == p[j])
            {
                i++;
                j++;
                nextval[i] = j;
                if(j > maxlen)   //求其中重复最大的字符串的个数,也就是与前面最前串的重复数
                    maxlen = j;
            }
            else
                j = nextval[j];
        }
        return maxlen;
    }
    
    int main()
    {
        char s[100];
        cin >> s;
        int maxlen = 0;//最大串的个数
        int nextMax; //Get_next函数得到的最大值
        int i;
        int maxIndex;
        int len = strlen(s);
        for(i = 0; i < len-1; i++)
        {
            int *next = new int[len - i];
            nextMax = Get_next(s + i, next);
            if(nextMax > maxlen)
            {
                maxIndex = i;
                maxlen = nextMax;
            }
        }
        cout << "输出最长重复子串:" << endl;
        for(i = 0; i < maxlen; i++)
            cout << s[i + maxIndex];
        cout << endl;
    }

      使用KMP的特性来解决这道题,时间复杂度有点高啊。

      事情总有解决的方法,所以就有了后缀数组这一数据结构来解决这个方法。对一个字符串生成相应的后缀数组后,再排序,排序后依次检测相邻的两个字符串的开头部分。

    #include <iostream>
    #include <cstring>
    #include <stdio.h>
    #include <algorithm>
    using namespace std;
    #define MAXLEN 10000
    char str[MAXLEN], *arr[MAXLEN];
    
    int CalLen(const char *str1, const char *str2)
    {
        int len = 0;
        while(*str1 && (*str1++ == *str2++))
            len++;
        return len;
    }
    
    int pStrCmp(const void *str1, const void *str2)
    {
        return strcmp(*(const char **)str1, *(const char **)str2);
    }
    
    int main()
    {
        char ch;
        int n = 0;
        int maxlen = 0, maxIndex = 0;
        int temp;
        while((ch = getchar()) != '
    ')
        {
            arr[n] = &str[n];
            str[n++] = ch;
        }
        str[n] = '';
        qsort(arr, n, sizeof(char *), pStrCmp);
        for(int i = 0; i < n - 1; i++)
        {
            temp = CalLen(arr[i], arr[i + 1]);
            if(temp > maxlen)
            {
                maxlen = temp;
                maxIndex = i;
            }
        }
        cout << arr[maxIndex] << endl;;
    }
  • 相关阅读:
    Web开发利器Webstorm导入多个文件夹或者项目
    js react 全选和反选
    nginx的配置文件 【nginx.conf】
    nginx 服务器重启命令,关闭
    Nginx反向代理新篇-使用location对多个URL做反向代理
    Windows下Nginx的安装与配置
    es6 递归 tree
    自定义table样式
    数据库(7)
    数据库(6)
  • 原文地址:https://www.cnblogs.com/awy-blog/p/3991838.html
Copyright © 2011-2022 走看看