寻找可能的前缀回文

时间:2019-04-22 11:18:47

标签: c++

我们给了一个长度为N的字符串S。我们必须计算可以重新排列成回文式的前缀数。例如:考虑字符串“ abba”-“ a”,“ abb”和“ abba”是可以重新排列成回文的前缀。

我的方法: 我试图使用XOR解决此问题。例如,如果字符串中所有字符的异或为0,则可以将包含偶数个字符的字符串设为回文。如果字符串具有奇数字符,则所有字符的异或应在97到122之间,即单个字符。

这是我的代码的一部分-

    string s;
    cin>>s;
    int a,n;
    int ans=1;
    n= s.length();
    a=s[0];
    for (int i=1;i<n;i++)
        {
            a=a^(s[i]);
            if (i%2)
            {
                if (a==0)
                {
                    ans++;
                }
            }
            else
            {
                if ((a>=97)&&(a<=122))
                {
                    ans++;
                }
            }
        }
    cout<< ans<< "\n";

我尝试运行,它在某些测试用例中成功运行,但在其他测试用例中却失败了。知道这种方法有什么问题吗?

1 个答案:

答案 0 :(得分:0)

更好的解决方案,基于OP的评论:

#include <string>
#include <iostream>
#include <cctype>

int main() {
    std::string input;
    std::cin >> input;

    unsigned char_xor   = input[ 0 ];
    unsigned pal        = 1; // number of palindromes (initialized to 1, 
                             // since a singular letter is always a 
                             // palindrome)

    for ( std::string::size_type i = 0; input.size() >= i; ++i ) {
        char_xor ^= input[ i + 1 ];

        // check whether length of current prefix is:
        //   - odd: check whether it is a lowercase character
        //   - even: check whether it is equal to 0
        if ( ( i % 2 && std::islower( char_xor ) ) ||
             ( !( i % 2 ) && !char_xor ) ) {
            ++pal;
        }
    }

    std::cout << "Amount of possible palindromes: " << pal << std::endl;

    return 0;
}

以下假设不正确(请参见下面的评论)。

根据

的理解
  

如果字符串中所有字符的异或为0,则可以将包含偶数个字符的字符串设为回文。如果字符串中包含奇数字符,则所有字符的异或应在97和122之间

在检查每次迭代中计算出的XOR是否等于0/97与122之间(在XOR插入每个字符之后)时,您犯了一个错误,而您应该在之后检查它遍历整个std::string。以下示例适用于您给定的示例“ abba”,例如“ aaaadcasdasdaffaaa”(产生了12个):

#include <string>
#include <iostream>
#include <cctype>

bool can_be_palindrome( const std::string& str ) {
    unsigned char_xor = str[ 0 ];

    // compute the xor of all characters
    for ( std::string::size_type i = 1; str.size() != i; ++i ) {
        char_xor ^= str[ i ];
    }

    // determine whether the input string has an even number of characters;
    // if so, return whether char_xor is equal to 0;
    // if not, return whether char_xor is a lowercase letter.
    return !( str.size() % 2 ) ? !char_xor : std::islower( char_xor );
}

int main() {
    std::string input;
    std::cin >> input;

    unsigned pal = 1; // number of palindromes (initialized to 1, since a 
                      // singular letter is always a palindrome)

    for ( std::string::size_type i = 2; input.size() >= i; ++i ) {
        // extract a prefix from the range [0; i) and determine whether it 
        // can become a palindrome
        if ( can_be_palindrome( input.substr( 0, i ) ) ) {
            ++pal;
        }
    }

    std::cout << "Amount of possible palindromes: " << pal << std::endl;

    return 0;
}