添加字符判断是否为回文串

Posted halotrriger

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了添加字符判断是否为回文串相关的知识,希望对你有一定的参考价值。

题目:给定一个字符串,问是否能通过添加一个字母将其变为回文串。

提要:所有代码皆为C++语言。

看到题,首先想到如何判断回文串
注:回文串添加或删除指定字符一定还是回文串。

对于一个字符串,从左右两端开始,以此判断,直到读取超出字符串中间。

代码如下:

#include<iostream>
#include<string.h>
using namespace std;
bool JudgeReverseString(char *str)
{
    //对比对应位置字符是否相同
    int len = strlen(str);
    for (int i = 0; i < len/2; ++i)
    {
        if (str[i] != str[len - i - 1])
            return false;
    }
    return true;
}

int main()
{
    char *str = (char*)malloc(100);
    memset(str, 0, 10);
    cin >> str;
    bool result = JudgeReverseString(str);
    if(result==true)
        cout<<"Yes!";
    else
        cout<<"No!";
}

方法一(不建议,因为时间复杂度为O(n^2))

一个字符串既然能插入对应字符构成回文串,那么删掉与之对应的字符,也一定能构成回文串。

#include<iostream>
#include<string.h>
using namespace std;
//判断回文串,在基础的回文串判断方法进行改进
bool JudgeReverseString(const char *str,int len)
{
    //对比对应位置字符是否相同
    for (int i = 0; i < len / 2; ++i)
    {
        if (str[i] != str[len - i - 1])
            return false;
    }
    return true;
}
//插入一个字符是回文串,那么删掉对应需要删除的字符则还能构成回文串
//判断删除一个字符是否还是回文串
bool DeleteCharIsReverseString(const char str[])
{
    char *copy_str = (char*)malloc(strlen(str));
    for (int i = 0; i<strlen(str); ++i)
    {
        strncpy(copy_str, str,strlen(str));
        for (int j = i; j<strlen(str); ++j)
        {
            copy_str[j] = copy_str[j + 1];
        }
        if (JudgeReverseString(copy_str,strlen(str)-1) == true)
            return true;
    }
    return false;
}

int main()
{
    char *str = (char*)malloc(1000);
    memset(str, 0, 1000);
    while(cin >> str)
    {
        bool result = DeleteCharIsReverseString(str);
        if (result == true)
            cout << "YES"<<endl;
        else
            cout << "NO"<<endl;
    }
    return 0;
    
}

方法二(在方法一的思想进行改进,摘自牛客网)

链接:https://www.nowcoder.com/questionTerminal/655a43d702cd466093022383c24a38bf
来源:牛客网
增加一个是回文,那删除一个也是回文。
具体删除方式可以采取模拟的方式,头尾遍历,i,j各指向头尾,如果相同则i++,j--。如果不同则说明出现不同,需要删除某个数故x--。
然后看str[i+1]是否等于str[j],是则删除第i个;或者看str[i]是否等于str[j-1],是则删除第j个;如若都不成立,则说明两个都得删除。
当删除个数大于等于2时,跳出循环。说明要构成回文需要删除两个以上字符故NO;
删除个数小于等于1时,则说明不删除或者删除一个就能构成回文,即添加一个也能构成回文,故YES!附上AC代码

#include<iostream>
#include<string>
using namespace std;
int main() {
    string str;
    while (cin >> str) {
        int i, l = str.length(), x = 2, j = l - 1;
        for (i = 0; i<j; i++, j--) 
        {
            if (str[i] != str[j]) 
            {
                x--;
            if (str[i + 1] == str[j])
                i++;
            else if (str[i] == str[j - 1])
                j--;
            else
                x--;
            }
        }
        if (x>0)
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    }
}

方法三(采用加入字符判断)

#include<iostream>
#include<string>
using namespace std;
//判断是否是回文串,是的话返回-1,不是的话对应位置返回下标
//因为失败要返回下标,所以满足条件并没有采取返回非负值而是-1
int IsPalindromeString(string str)
{
    //对比对应位置字符是否相同
    int len = str.size();
    for (int i = 0; i < len / 2; ++i)
    {
        if (str[i] != str[len - i - 1])
            return i;
    }
    return -1;
}

bool InsertCharIsParlindromString(string str)
{
    int size = str.size();
    int pos = IsPalindromeString(str);
    //本身不是回文串
    if (pos != -1)
    {
        //代码思想:从不一致的位置开始,取到右边与它对应位置的子串
        //在子串前面加子串的末尾值,或者在子串末尾加子串的最前值
        //原因如下,符合条件的话会满足其中一个
        //如果是左边缺,则子串末尾的值就是左边缺的,添回就是回文串
        //如果是右边缺,则子串开始的值就是右边缺的,添回就是回文串

        //右边与pos对应的位置的值 加上 pos开始,长度size-2*pos的子串
        int result1 = IsPalindromeString(str[size - 1 - pos] + str.substr(pos, size - 2 * pos));
        //pos开始,长度size-2*pos的子串 加上 pos位置的值
        int result2 = IsPalindromeString(str.substr(pos, size - 2 * pos) + str[pos]);
        if ((result1 == -1) || (result2 == -1))
            return true;
        else
            return false;
    }
    //本身是回文串,添加指定字符还是回文串
    else
    {
        return true;
    }
}


int main()
{
    string str;
    while (cin >> str)
    {
        bool result = InsertCharIsParlindromString(str);
        if (result == true)
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    }
    return 0;
}

技术分享图片

有什么问题欢迎各位读者提问,谢谢!








以上是关于添加字符判断是否为回文串的主要内容,如果未能解决你的问题,请参考以下文章

算法系列——判断是否为回文字符串

算法系列——判断是否为回文字符串

算法系列——判断是否为回文字符串

给定一个字符串,问是否能通过添加一个字母将其变为回文串。

C语言:编写一个测试一个串是不是为回文的递归函数,是回文,返回1;不是,返回0。

判断是否为回文串