挑战编程:回文字符串

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Matthew_Fan/article/details/10182711

题目描述:

回文字符串是指从左到右和从右到左相同的字符串,现给定一个仅由小写字母组成的字符串,你可以把它的字母重新排列,以形成不同的回文字符串。

输入:非空仅由小写字母组成的字符串,长度不超过100;
输出:能组成的所有回文串(因为结果可能非常大,输出对1000000007取余数的结果)。

例如:输入"aabb" 输出为2,输出对应的所有回文字符串:abba和baab

函数头部 c: int palindrome(const char *s); c++ int palindrome(const string &s);

挑战规则:
main函数可不用完成

对比数据:
864920675:aaaabbbbcccceeeeddddddffffgggghhhhjjjjiiiikkkkkkkkkkkkkkkkllllll
2:aabb
2520:fdfdfdfdeeeeerrrr
7560:fdfdfdfdqqqqqqwwwww
0:aaabbb


题目分析:

1、内部包含的每个字符的个数为奇数的数量,不能超过1个

2、每个字符在挑选位置时,可以理解成一个组合C(n, j)

3、取余公式

(a + b) mod m = ((a mod m) + (b mod m)) mod m
(a*b) mod m = ((a mod m) * (b mod m)) mod m


例如:fdfdfdfdqqqqqqwwwww

{f,d,q,w}对应的个数{4,4, 6, 5},那么放在中间位置应该是‘w’。那么当前的字符串为“#########w#########”,我只考虑半个字符串“#########”。则{f,d,q,w}对应的数目为{2, 2, 3, 2},所以用统计学的方法不难发现其值为C(9,2)*C(7,2)*C(5,3)*C(2,2)


#include <iostream>
#include <string>

using namespace std;

int palindrome(const string &s);
int main()
{
	string str = "aaaabbbbbbcccceeeeddddddffffgggghhhhjjjjiiiikkkkkkkkkkkkkkkkllllll";
	cout << palindrome(str) << endl;
	getchar();
	return 0;
}

// 统计学中组合的求发:C(iMax, index)
int GetCombination(int imax, int index)
{
	int result = 1;
	int iDivider = 1;

	for (int i = 1; i <= index; i ++)
	{
		result = result * imax;
		if (i <= index)
		{
			iDivider = iDivider*i;
		}
		imax --;
	}

	return result / iDivider;
}

int palindrome(const string &s)
{
	unsigned long long palindromeTotal = 1;
	const unsigned int modulus = 1000000007;

	int recordArr[26] = {0};
	int ia = (int)'a';

	// 获取每个字符的个数表
	for (int i = 0; i < s.size(); i ++)
	{
		int index = (int)s[i] - ia;
		recordArr[index] ++;
	}
	
	int iOddTotals = 0;
	int iMaxIndexTotal = 0;
	for (int i = 0; i < 26; i ++)
	{
		if (recordArr[i] != 0)
		{
			if (recordArr[i] % 2 != 0)
			{
				iOddTotals ++;
				recordArr[i] --;
			}
			recordArr[i] = recordArr[i] / 2;
			iMaxIndexTotal += recordArr[i]; 
		}
	}

	if (iOddTotals > 1)
	{
		return 0;
	}
	
	unsigned int res = 0;
	for (int i = 0; i < 26; i ++)
	{
		if (recordArr[i] != 0)
		{
			// 计算余数的算法,这样可以数据防止越界
			//原理:
			//(a + b) mod m = ((a mod m) + (b mod m)) mod m
			//(a*b) mod m = ((a mod m) * (b mod m)) mod m
			palindromeTotal = palindromeTotal * GetCombination(iMaxIndexTotal, recordArr[i]);
			palindromeTotal %= modulus;

			iMaxIndexTotal -= recordArr[i];
		}
	}
	
	return (int)palindromeTotal;
}



猜你喜欢

转载自blog.csdn.net/Matthew_Fan/article/details/10182711