简体   繁体   English

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

[英]Find All Palindrome Substrings in a String by Rearranging Characters

For fun and practice, I have tried to solve the following problem (using C++): Given a string, return all the palindromes that can be obtained by rearranging its characters. 为了娱乐和练习,我尝试解决以下问题(使用C ++): Given a string, return all the palindromes that can be obtained by rearranging its characters.

I've come up with an algorithm that doesn't work completely. 我想出了一种无法完全起作用的算法。 Sometimes, it finds all the palindromes, but other times it finds some but not all. 有时,它会找到所有回文,而在其他时候,它会发现一些但不是全部。

It works by swapping each adjacent pair of characters N times, where N is the length of the input string. 它通过将每对相邻的字符对N次交换来工作,其中N是输入字符串的长度。 Here is the code: 这是代码:

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;
}

What's the fault in this algorithm? 该算法有什么问题? I'm mostly concerned about the functionality of the algorithm, rather than the efficiency. 我最关心的是算法的功能,而不是效率。 Although I'll appreciate tips about efficiency as well. 尽管我也会感谢有关效率的提示。 Thanks. 谢谢。

This probably fits a bit better in Code Review but here goes: 这在“代码审查”中可能更合适,但这里是:

Logic Error 逻辑错误

You change charactersSet while iterating over it, meaning that your iterator breaks. 您在迭代时更改charactersSet ,这意味着迭代器将中断。 You need to make a copy of characterSet , and iterate over that. 您需要复制characterSet ,并对其进行迭代。

Things to Change 改变的事情

Since pals holds only unique values, it should be a std::set instead of a std::vector . 由于pals仅持有唯一值,因此应为std::set而不是std::vector This will simplify some things. 这将简化一些事情。 Also, your isPalandrome method spells palindrome wrong! 另外,您的isPalandrome方法将回文拼写错误!

Alternative Approach 替代方法

Since palindromes can only take a certain form, consider sorting the input string first, so that you can have a list of characters with an even number of occurrences, and a list of characters with an odd number. 由于回文仅能采用某种形式,因此请考虑首先对输入字符串进行排序,以便您可以看到出现偶数的字符列表和出现奇数的字符列表。 You can only have one character with an odd number of occurrences (and this only works for an odd length input). 您只能使用一个出现奇数次的字符(这仅适用于奇数长度的输入)。 This should let you discard a bunch of possibilities. 这应该让您放弃很多可能性。 Then you can work through the different possible combinations of one half of the palindrome (since you can build one half from the other). 然后,您可以研究回文的一半的不同可能组合(因为您可以从另一半构建另一半)。

Here is another implementation that leverages std::next_permutation : 这是另一个利用std::next_permutation

#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;
}

We first sort the original string. 我们首先对原始字符串进行排序。 This is required for std::next_permutation to work correctly. 这是std::next_permutation正常工作所必需的。 A call to the isPalindrome function with a permutation of the string is done in a loop. 在一个循环中调用带有字符串置换的isPalindrome函数。 Then if the string is a palindrome, it's stored in the set. 然后,如果字符串是回文,则将其存储在集合中。 The subsequent call to std::next_permutation just rearranges the string. 随后对std::next_permutation调用只是重新排列了字符串。

Here is a Live Example . 这是一个实时示例 Granted, it uses a reversed copy of the string as the "isPalindrome" function (probably not efficient), but you should get the idea. 当然,它使用字符串的反向副本作为“ isPalindrome”函数(可能效率不高),但是您应该明白这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM