最大对称字符串的算法

 更新时间:2013年03月06日 15:43:03   作者:  
题目:输入一个字符串,输出该字符串中对称的子字符串的最大长度。比如输入字符串“google”,由于该字符串里最长的对称子字符串是“goog”,因此输出4。

算法一:O(n^3)

判断字串是否对称是从外到里, O(n)


复制代码 代码如下:

#include <stdio.h>
#include <string.h>

/*
 *判断起始指针,到结束指针的字符串是否对称
 */
int IsSymmetrical(char* pBegin, char* pEnd)
{
    if(pBegin == NULL || pEnd == NULL || pBegin > pEnd)
    return 0;

    while(pBegin < pEnd)
    {
    if(*pBegin != *pEnd)
        return 0;
    pBegin++;
    pEnd--;
    }
    return 1;
}

/*
 *查找最大对称字串长度,时间复杂度是O(n^3)
 */
int GetLongestSymmetricalLength(char* pString)
{
    if(pString == NULL)
    return 0;
    int symmetricalLength = 1;
    char* pFirst = pString;
    int length = strlen(pString);

    while(pFirst < &pString[length-1])
    {
    char* pLast = pFirst + 1;
    while(pLast <= &pString[length-1])
    {
        if(IsSymmetrical(pFirst, pLast))
        {
        int newLength = pLast - pFirst + 1;
        if(newLength > symmetricalLength)
            symmetricalLength = newLength;
        }
        pLast++;
    }
    pFirst++;
    }
    return symmetricalLength;
}

int main()
{
    char* str = "google";
    int len = GetLongestSymmetricalLength(str);
    printf("%d", len);
    return 0;
}


算法2: O(n^2)

判断字串是否对称是从外到里, O(1)

复制代码 代码如下:

#include <stdio.h>
#include <string.h>


int GetLongestSymmetricalLength(char* pString)
{
    if(pString == NULL)
    return 0;
    int symmetricalLength = 1;

    char* pChar = pString;
    while(*pChar != '\0')
    {
    //奇数长度对称, 如 aAa
    char* left = pChar - 1;
    char* right = pChar + 1;
    while(left >= pString && *right != '\0' && *left==*right)
    {
        left--;
        right++;
    }
    int newLength = right - left - 1;   //退出循环是*left!=*right
    if(newLength > symmetricalLength)
        symmetricalLength = newLength;

    //偶数长度对称, 如 aAAa
    left = pChar;
    right = pChar + 1;
    while(left >= pString && *right != '\0' && *left==*right)
    {
        left--;
        right++;
    }
    newLength = right - left - 1;   //退出循环是*left!=*right
    if(newLength > symmetricalLength)
        symmetricalLength = newLength;

    pChar++;
    }

    return symmetricalLength;
}

int main()
{
    char* str = "google";
    int len = GetLongestSymmetricalLength(str);
    printf("%d", len);
    return 0;
}

算法3:manacher算法

 原串:abaab
新串:#a#b#a#a#b#
这样一来,原来的奇数长度回文串还是奇数长度,偶数长度的也变成以‘#'为中心的奇数回文串了。
接下来就是算法的中心思想,用一个辅助数组P记录以每个字符为中心的最长回文半径,也就是P[i]记录以Str[i]字符为中心的最长回文串半径。P[i]最小为1,此时回文串为Str[i]本身。
我们可以对上述例子写出其P数组,如下
新串: # a # b # a # a # b #
P[]  :  1 2 1 4 1 2 5 2 1 2 1
我们可以证明P[i]-1就是以Str[i]为中心的回文串在原串当中的长度。
证明:
1、显然L=2*P[i]-1即为新串中以Str[i]为中心最长回文串长度。
2、以Str[i]为中心的回文串一定是以#开头和结尾的,例如“#b#b#”或“#b#a#b#”所以L减去最前或者最后的‘#'字符就是原串中长度的二倍,即原串长度为(L-1)/2,化简的P[i]-1。得证。

注: 不是很懂, 自己改了

复制代码 代码如下:

#include <stdio.h>
#include <string.h>

int GetLongestSymmetricalLength(char* pString)
{
    int length = strlen(pString);
    char* pNewString = malloc(2*length+2);
    int i;
    for(i=0; i<length; i++)
    {
    *(pNewString+i*2) = '#';
    *(pNewString+i*2+1) = *(pString+i);
    }
    *(pNewString+2*length) = '#';
    *(pNewString+2*length+1) = '\0';

    printf("%s\n", pNewString);
    int maxLength = 1;
    char* pChar;
    for(i=0; i<2*length+2; i++)
    {
    int newLength = 1;
    pChar = pNewString + i;
    char* left = pChar-1;
    char* right = pChar+1;
    while(left>=pNewString && *right!='\0'&& *left==*right)
    {
        left--;
        right++;
        newLength++;
    }
    if(newLength > maxLength)
        maxLength = newLength;
    }

    return maxLength-1;
}

int main()
{
    char* str = "google";
    int len = GetLongestSymmetricalLength(str);
    printf("%d", len);
    return 0;
}

相关文章

  • QT编写窗口插件实现调用窗口的自适应

    QT编写窗口插件实现调用窗口的自适应

    这篇文章主要为大家详细介绍了QT编写窗口插件实现调用窗口的自适应,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-06-06
  • C++ lambda函数详解

    C++ lambda函数详解

    小编可以明确告诉大家:lambda函数是C++11中最重要的,使用最广泛的,最具现代风格的内容,lambda函数的出现改变了C++编程的思维方式。所以快和小编学习一下C++11中lambda函数的使用吧
    2023-02-02
  • C++实现井字棋游戏

    C++实现井字棋游戏

    这篇文章主要为大家详细介绍了C++实现井字棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-07-07
  • 基于VC实现的网络监听功能程序实例

    基于VC实现的网络监听功能程序实例

    这篇文章主要介绍了基于VC实现的网络监听功能程序,需要的朋友可以参考下
    2014-07-07
  • 在Ubuntu中安装VSCode并配置C/C++开发环境的方法步骤

    在Ubuntu中安装VSCode并配置C/C++开发环境的方法步骤

    这篇文章主要介绍了在Ubuntu中安装VSCode并配置C/C++开发环境的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-05-05
  • C++设计模式之代理模式(Proxy)

    C++设计模式之代理模式(Proxy)

    这篇文章主要为大家详细介绍了C++设计模式之代理模式的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • C/C++ Zlib库封装MyZip压缩类的详细过程

    C/C++ Zlib库封装MyZip压缩类的详细过程

    在软件开发中,文件的压缩和解压缩是一项常见的任务,而ZIP是一种被广泛应用的压缩格式,本文将聚焦于一个简化的C++实现,通过分析代码,我们将深入了解其设计和实现细节,感兴趣的朋友一起看看吧
    2023-11-11
  • VS2019配置BOOST的方法(v1.70.0库)

    VS2019配置BOOST的方法(v1.70.0库)

    这篇文章主要介绍了VS2019配置BOOST的方法(v1.70.0库),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • C++实现文件逐行读取与字符匹配的示例详解

    C++实现文件逐行读取与字符匹配的示例详解

    这篇文章主要为大家详细介绍了如何溧阳C++实现文件逐行读取与字符匹配的功能,文中的示例代码讲解详细,具有一定的借鉴价值,需要的可以参考一下
    2023-03-03
  • C++ lambda 捕获模式与右值引用的使用

    C++ lambda 捕获模式与右值引用的使用

    这篇文章主要介绍了C++ lambda 捕获模式与右值引用的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03

最新评论