回文字符串
还是在庞果网看到的题目,这次选了个简单的,回文字符串。
题目内容
回文字符串是指从左到右和从右到左相同的字符串,现给定一个仅由小写字母组成的字符串,你可以把它的字母重新排列,以形成不同的回文字符串。
- 输入:非空仅由小写字母组成的字符串,长度不超过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; }
四则运算和取模的字符串操作没贴了,有点多而且不是算法核心,而且网上一大把,我也是网上找的,就不贴了。