还是在庞果网看到的题目,这次选了个简单的,回文字符串。
题目内容
回文字符串是指从左到右和从右到左相同的字符串,现给定一个仅由小写字母组成的字符串,你可以把它的字母重新排列,以形成不同的回文字符串。
- 输入:非空仅由小写字母组成的字符串,长度不超过100;
- 输出:能组成的所有回文串的个数(因为结果可能非常大,输出对1000000007取余数的结果)。
例如:输入"aabb" 输出为2(因为“aabb”对应的所有回文字符串有2个:abba和baab)
思路
- 判断出该字符串是否能形成回文
能否形成回文,必须满足:- 要么所有元素的个数都是偶数
- 要么有一个元素的个数是奇数,其他的都是偶数
- 不满足上面条件的直接返回0,因为这样构不成回文
- 判断出能形成回文以后,将元素减半,在字符串一半的长度内进行组合操作,即排列组合中的Cmn,n表示某个元素的个数,m表示字符串的剩余长度。
比如例子中,判断完以后还剩a和b两个元素,每个元素个数都是1,字符串长度为2,那回文数的个数是:C(2,1)*C(1,1) 这是一个标准组合和乘法法则 - 计算Cmn的时候会出现极大的数,造成溢出,所以要实现大数据的加减乘除,这样的代码网上大把的,理解以后加入就行了,实际上就是用字符串表示加减乘除。
完成以上三点,就完成题目了,这次提交后终于挑战成功了。。。。
#include <string>
#include <vector>
#include <iostream>
#include <set>
#include <map>
#include <math.h>
using namespace std;
//计算某个字符的个数,每次都是计算首字符的个数,计算完后将该字符从字符串中清除
int howMany(string &str)
{
if(str.size()==1)
{
str.erase(0,1);
return 1;
}
if(str.size()==0)
return 0;
string::iterator it;
char cmp=str[0];
int count=0;
for(int i=0;i<str.size();i++)
{
if(cmp==str[i])
{
count++;
str.erase(i,1);
i--;
}
}
//cout << str << endl;
return count;
}
/* 辅助函数,字符串四则运算和取模开始 */
int COMPARE(string number1, string number2)
{
}
string PLUS(string number1,string number2)
{
}
string MINUS(string number1,string number2)
{
}
string MULTIPLY(string number1, string number2)
{
}
string DIVIDE(string number1, string number2, int floatpoint = 0)
{
}
string MOD(string number1, string number2)
{
}
/* 字符串四则运算和取模结束 */
//阶乘
string fib(int x)
{
string X;
char t[256];
sprintf(t, "%d", x);
X = t;
if(x==0)
return "1";
else
return MULTIPLY(X,fib(x-1));
}
//计算组合数
string Combination(int m,int n)
{
string res;
vector<int> com;
vector<int>::iterator it;
for(int i=1;i<n;i++)
{
if(i>=(n-m))
com.push_back(i);
}
//cout << "Combination "<< m <<" " << n << " is ";
res=DIVIDE(DIVIDE(fib(n),fib(m),0),fib(n-m),0);
//cout << res << endl;
return res;
}
//入口函数
int palindrome(const string &s)
{
string str=s;
cout << str << endl;
int count;
int flag=0;
int totel=0;
vector<int> counts;
string resStr;
resStr="1";
do
{
//cout << " Char [" << str[0] << "] has " ;
//计算每个字符的个数
count= howMany(str);
//cout << count << endl;
//判断奇数的个数
if(count % 2 !=0)
{
if(flag==0)
{
totel=totel+(count-1)/2;
counts.push_back(count/2);
flag++;
}else
{
flag++;
}
}else
{
totel=totel+count/2;
counts.push_back(count/2);
}
}while(count!=0);
if(flag == 1 || flag ==0 )
{
cout << "has palindrome string,totel is " << totel << endl;
}else
{
cout << "no palindrome string" <<endl;
return 0;
}
for(int i=0;i<counts.size();i++)
{
//cout << "count[" << i << "] :" << counts[i] << endl;
//计算组合数
resStr=MULTIPLY(resStr,Combination(counts[i],totel));
totel=totel-counts[i];
}
//cout <<"The Res is " << MOD(resStr,"1000000007") << endl;
//结果对1000000007取余
return atoi(MOD(resStr,"1000000007").c_str());//res%1000000007;
}
int main()
{
#if 1
string str="aabbdccddjjkkiiuuyiijjqkkkkkk2222224444446666qqqqqqqqqqqqqqqqqqqqqjjkkqqooddmmffyyyllooppqq";
cout << " the Res is "<< palindrome(str) << endl;
#endif
return 0;
}