对于一个字符串对其添加一个字符可以构成回文字符串吗
方法一:逆思维思考
对于添加一个字符可以构成回文字符串的话,那么删除一个字符也就可以构成回文字符串了,所以就可以对于这个字符串的每一个字符进行删除,然后在判断是不是回文字符串,如果是的话,那就可以,否则不可以
代码实现:
#include <iostream>
#include <string>
//判断一个字符串是不是回文字符串
bool Check(const std::string& str)
{
int len = str.size();
for (size_t i = 0; i < len / 2; i++)
{
if (str[i] != str[len - i - 1])
{
return false;
}
}
return true;
}
int main()
{
std::string str;
//char str1[1000];
//std::cin >> str1;
//str = str1;
bool flag;
while (std::cin >> str)
{
for (size_t i = 0; i < str.size(); i++)
{
std::string tmpStr = str;
for (size_t j = i; j < str.size(); j++)
{
tmpStr[j] = tmpStr[j + 1];
}
tmpStr.resize(str.size() - 1);
if (flag = Check(tmpStr))
{
std::cout << "YES" << std::endl;
break;
}
}
if (!flag)
std::cout << "NO" << std::endl;
}
return 0;
}
方法二:对于方法一进行改进
设置i和j,分别是最左边和最右边下标,每次比较左右两边相同位置的字符,相同的话就继续比较。设置一个x表示的是删除字符串限制,x=2表明最多可以删除一个字符
否则的话将i++之后和j继续比较,或者j--之后和i继续比较(此时x--),如果可以一直比完的话,那就是回文的字符串,也就相当于删除一个字符串。
如果都不可以话,那就说明删除一个字符无法变成回文字符串(x--),需要删除至少两个才可以构成回文字符串
最后只需要判断x就可以知道是否可以构成回文字符串
代码实现:
std: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;
}
方法三:
也是设置一个i和j指针,分别从两变相同的位置向中间比较,直到不相同位置。
此时如果要添加一个字符构成回文字符串的话,那就是将左边的添加到右边,或者将最后边的添加到左边
再次对添加之后的字符串进行判断是不是回文字符串,如果是的话可以,否则失败
代码实现:
//判断是否是回文串,是的话返回-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;
}
插图: