C++ 通过重新排列字符来查找字符串中的所有回文子字符串

C++ 通过重新排列字符来查找字符串中的所有回文子字符串,c++,algorithm,palindrome,C++,Algorithm,Palindrome,为了好玩和练习,我尝试解决以下问题(使用C++):给定一个字符串,返回可以通过重新排列其字符获得的所有回文。 我想出了一个不完全有效的算法。有时,它会找到所有的回文,但有时它会找到一些但不是全部 它通过交换每对相邻的字符N次来工作,其中N是输入字符串的长度。代码如下: std::vector<std::string> palindromeGen(std::string charactersSet) { std::vector<std::string> pals;

为了好玩和练习,我尝试解决以下问题(使用C++):
给定一个字符串,返回可以通过重新排列其字符获得的所有回文。

我想出了一个不完全有效的算法。有时,它会找到所有的回文,但有时它会找到一些但不是全部

它通过交换每对相邻的字符
N
次来工作,其中
N
是输入字符串的长度。代码如下:

std::vector<std::string> palindromeGen(std::string charactersSet) {
    std::vector<std::string> pals;
    for (const auto &c : charactersSet) {
        for (auto i = 0, j = 1; i < charactersSet.length() - 1; ++i, ++j) {
            std::swap(charactersSet[i], charactersSet[j]);
            if (isPalandrome(charactersSet)) {
                if (std::find(pals.begin(), pals.end(), charactersSet) == pals.end()) {
                    // if palindrome is unique
                    pals.push_back(charactersSet);
                }
            }
        }
    }
    return pals;
}
std::向量回文元(std::字符串字符集){
std::向量pals;
用于(常量自动和c:字符集){
对于(自动i=0,j=1;i

这个算法有什么毛病?我最关心的是算法的功能,而不是效率。虽然我也很欣赏关于效率的建议。谢谢。

这可能更适合代码审查,但下面是:

逻辑错误 在迭代过程中更改
字符集
,这意味着迭代器将中断。您需要复制一份
字符集
,并对其进行迭代

需要改变的事情 由于
pals
只保存唯一的值,因此它应该是
std::set
而不是
std::vector
。这将简化一些事情。另外,您的
isplandrome
方法拼写回文错误

替代方法

由于回文只能采取某种形式,首先考虑对输入字符串进行排序,这样就可以有偶数出现的字符列表和奇数字符列表。只能有一个出现次数为奇数的字符(这仅适用于奇数长度输入)。这会让你放弃很多可能性。然后,您可以处理回文的一半的不同可能组合(因为您可以从另一半构建回文的一半)。

这可能更适合于代码评审,但如下所示:

逻辑错误 在迭代过程中更改
字符集
,这意味着迭代器将中断。您需要复制一份
字符集
,并对其进行迭代

需要改变的事情 由于
pals
只保存唯一的值,因此它应该是
std::set
而不是
std::vector
。这将简化一些事情。另外,您的
isplandrome
方法拼写回文错误

替代方法

由于回文只能采取某种形式,首先考虑对输入字符串进行排序,这样就可以有偶数出现的字符列表和奇数字符列表。只能有一个出现次数为奇数的字符(这仅适用于奇数长度输入)。这会让你放弃很多可能性。然后,您可以处理回文的一半的不同可能组合(因为您可以从另一半构建另一半)。

这里是另一个利用
std::next\u排列的实现:

#include <string>
#include <algorithm>
#include <set>

std::set<std::string> palindromeGen(std::string charactersSet) 
{
    std::set<std::string> pals;
    std::sort(charactersSet.begin(), charactersSet.end());
    do
    {
        // check if the string is the same backwards as forwards
        if ( isPalindrome(charactersSet)) 
           pals.insert(charactersSet);
    } while (std::next_permutation(charactersSet.begin(), charactersSet.end()));
    return pals;
}
#包括

#包括。诚然,它使用字符串的反向副本作为“isAlindrome”函数(可能效率不高),但您应该明白这一点。

这里是另一个利用
std::next\u排列的实现:

#include <string>
#include <algorithm>
#include <set>

std::set<std::string> palindromeGen(std::string charactersSet) 
{
    std::set<std::string> pals;
    std::sort(charactersSet.begin(), charactersSet.end());
    do
    {
        // check if the string is the same backwards as forwards
        if ( isPalindrome(charactersSet)) 
           pals.insert(charactersSet);
    } while (std::next_permutation(charactersSet.begin(), charactersSet.end()));
    return pals;
}
#包括

#包括。诚然,它使用字符串的反向副本作为“isAlindrome”函数(可能效率不高),但你应该明白这一点。

Oops,这里的拼写错误很尴尬哈哈。谢谢你的建议。哦,糟糕的拼写错误,哈哈。谢谢你的建议。使用
std::set pals而不是向量。然后您不需要调用
std::find
,因为集合只存储唯一的项而不是向量。那么您就不需要调用
std::find
,因为集合只存储唯一的项目。谢谢!我还不知道下一个排列。谢谢!我不知道下一个排列。