回文字符串

gukuitian 2013-10-18 05:54:58
题目来源

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

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

例如:输入"aabb" 输出为2(因为“aabb”对应的所有回文字符串有2个:abba和baab)

算错了么,
628660165
...全文
417 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
gukuitian 2013-10-28
  • 打赏
  • 举报
回复
引用 11 楼 erqieshi 的回复:
(1+2+1+3)!/(1!*2!*1!*3!) =C(1,1)*C(3,2)*C(4,1)*C(7,3) 来代替 直接阶乘,非常容易溢出 //最大值C(50,25) //int 不够用 __int64就够了 但是直接阶乘__int64都不够用 你的在与用double算阶乘,能保证几位有效数字?
确实是double精度的事。 27阶乘错了。 1.0888869450418352E28 10888869450418352160768000000
erqieshi 2013-10-28
  • 打赏
  • 举报
回复
(1+2+1+3)!/(1!*2!*1!*3!) =C(1,1)*C(3,2)*C(4,1)*C(7,3) 来代替 直接阶乘,非常容易溢出 //最大值C(50,25) //int 不够用 __int64就够了 但是直接阶乘__int64都不够用 你的在与用double算阶乘,能保证几位有效数字?
gukuitian 2013-10-26
  • 打赏
  • 举报
回复
引用 2 楼 FancyMouse 的回复:
我做出来676517829
亲,说说是怎么算的呗
gukuitian 2013-10-26
  • 打赏
  • 举报
回复
引用 4 楼 erqieshi 的回复:
先统计字符出现次数 以a2c4d3e6为例 明显要左右各半a1c2d1e3 确定了左半,右半就也同样确定了 然后计算 (1+2+1+3)!/(1!*2!*1!*3!) 难题在于中间过程数越界的时候的操作
我想的和你差不多,可是结果好像不对:628660165

    public static void main(String[] args) {
	System.out.println(test1("hqaymehhrsfuqrpahrimsxftuxqrpsejouuehaqtsryxjhearxmogmi"));
    }
    
    static int test1(String s) {//aabb  A(5,5)/A(2,2)*(1+1/A(2,2))
	s = s.toLowerCase();
	int[] array = new int[26];
	for (int i = 0; i < s.length(); i++) {
	    array[s.charAt(i) - 97]++;
	}
	int temp = 0;
	double num=factorial(s.length()/2);
	for (int i : array) {
	    if (i == 0)
		continue;
	    if (i % 2 != 0 && temp++ > 0) {
		return 0;
	    }
	    num /= factorial(i>>1);
	}
	return (int)(num%1000000007);
    }
    /**
     * 阶乘
     * @param n
     */
    static double factorial(int n) {
	double rtnNum = 1;
	for (int i = 2; i <= n; i++) {
	    rtnNum *= i;
	}
	return rtnNum;
    }
Smile_Tiger 2013-10-25
  • 打赏
  • 举报
回复
网址不错,谢楼主分享
erqieshi 2013-10-22
  • 打赏
  • 举报
回复

int iBase = 1000000007;
//计算组合数C(m,n)//结果对iBase求余
int comb(int m,int n)
{
	if (n*2 > m)
	{
		return comb(m,m-n);
	}
//最大值C(50,2)
//int 不够用 __int64就够了
	__int64 ires = 1;
	for (int i=1;i<=n;i++)
	{
		ires *= m-n+i;		
		ires /= i;//利用下标从1开始的肯定能整除
//此时的ires = C(m_-n+i,i)
	}
	return (ires%iBase);
}

int palindrome(const char *s)
{
	int flag[256] = {0};
//统计字符出现次数
	while((*s)!='\0')
	{
		int index = *s + 128;
		flag[index]++;
		s++;
	}
	bool bsingl = false;//是否有奇数次字符
	int ires = 1;
	int itotal = 0;
	int ilength = 0;
	for(int i = 0;i<256;i++)
	{
		int icount = flag[i];
		if (icount%2 == 1)
		{
			if (bsingl)
			{
				return 0;
			}
			bsingl = true;			
		}
		icount /= 2;
		if (icount<1)
		{
			continue;
		}
		ilength+= icount;
		if (ilength>50)
		{
		//	return -1;
		}
		if (icount>0)
		{
			itotal += icount;
			ires %= iBase;
			int itemp = comb(itotal,icount);
			__int64 ires_64 = ires;
			ires_64 *= itemp;
			ires = (ires_64%iBase);
			printf("%d\n",ires);
		}
		
	}
	ires %= iBase;
	return ires;
}
int main()
{
	const char* str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";

	printf("\n%s\n%d",str,palindrome(str));
	str = "hqaymehhrsfuqrpahrimsxftuxqrpsejouuehaqtsryxjhearxmogmi";	
	printf("\n%s\n%d",str,palindrome(str));
    system ("pause");
    return 0;
}
答案是#2的676517829 我前面算错了
Moujiker 2013-10-21
  • 打赏
  • 举报
回复
好深奥的说!!!!
erqieshi 2013-10-21
  • 打赏
  • 举报
回复
419663680
erqieshi 2013-10-21
  • 打赏
  • 举报
回复
先统计字符出现次数 以a2c4d3e6为例 明显要左右各半a1c2d1e3 确定了左半,右半就也同样确定了 然后计算 (1+2+1+3)!/(1!*2!*1!*3!) 难题在于中间过程数越界的时候的操作
erqieshi 2013-10-21
  • 打赏
  • 举报
回复
428542839
FancyMouse 2013-10-19
  • 打赏
  • 举报
回复
我做出来676517829
gukuitian 2013-10-18
  • 打赏
  • 举报
回复
验证数据是:hqaymehhrsfuqrpahrimsxftuxqrpsejouuehaqtsryxjhearxmogmi 我得的结果:628660165 同学们算一算,看看错哪了。

33,027

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧