生成给定字符串的所有可能的回文

时间:2016-01-27 21:47:29

标签: c++ string algorithm palindrome

Inputs : I.1) A string of characters
Outputs: O.1) Total number of palindromes found
         O.2) Palindromes output on standard output

Note : duplicate palindromes are not allowed
             output need not be sorted
single characters are a palindrome.

我通过回溯解决了上述问题,但是它为一个大输入字符串提供了TLE。因此,如果解决方案避免递归将是有益的。 TLE的输入是: - amitabhbacchan
这是我的实施:

#include <iostream>
#include<bits/stdc++.h>
using namespace std;

int isSafe(int *a, int i) {
    if (a[i] == 0) {
        return 1;
    }
    else {
        return 0;
    }
}

int isPalin(string b) {
    if (b.length() == 0) {
        return 0;
    }
    if (b.length() == 1) {
        return 1;
    }
    string c = b;
    std::reverse(c.begin(), c.end());
    if (c == b) {
        return 1;
    }
    else {
        return 0;
    }
}

void palindrome(string a, string b, int *vec, std::set<string>&res) {

    if (isPalin(b)) {
        if (res.find(b) != res.end()) {
            return;
        }
        res.insert(b);
    }

    for (int i = 0; i < a.length(); i++) {
        if (isSafe(vec, i)) {
            b.push_back(a[i]);
            vec[i] = 1;

            palindrome(a, b, vec, res);
            b.pop_back();
            vec[i] = 0;
        }
    }
}

int main(void) {
    string a = "ababcdef";
    string c = "";
    int *vec;
    std::set<string>res;
    vec = (int*)malloc(a.length()*sizeof(int));
    for (int i = 0; i < a.length(); i++) {
        vec[i] = 0;
    }
    palindrome(a, c, vec, res);
    std::set<string>::iterator it;

    for (it = res.begin(); it != res.end(); it++) {
        cout << *it << endl;
    }
    return 0;
}

1 个答案:

答案 0 :(得分:1)

这里的基本问题是你非常低效地产生回文。特别是,您试图生成输入的每个可能的排列,然后检查每个输入是否是回文。

而不是那样,考虑字符串的基本要求是回文(中间的所有字符都与中间的字符相同,并且与中间的字符相反)。因此,除了奇数回文的中间字符之外,回文中的每个其他字符必须偶数次出现。

我首先将字符分成两组:偶数出现和奇数出现。偶数次出现的字符只插入工作集中的一半。也就是说,在输入中给出(例如)aabbccde,您可以将其分成两部分,一部分包含abc,另一部分包含de

然后,您可以通过生成abc(以及abacbc)的所有排列来生成您的回文,您可以按顺序输出,然后输出相反的顺序设置相同(例如,abc后跟cba给出abccba)。然后,对于其中每一个,您可以在中间插入另一个字符中的一个字符,这样您就可以获得abcdcbaabcecba)。然后重新排列这些输入以获取(例如)acb并重复该过程以获得acbbcaacbdbcaacbebca

生成&#34;偶数&#34;的所有排列的一种方法输入为std::next_permutation

请注意,这样您就不会花时间产生许多不属于回文的安排。您事先知道,您生成的每个结果成为回文。