還是在龐果網看到的題目,這次選了個簡單的,迴文字符串。
題目內容
迴文字符串是指從左到右和從右到左相同的字符串,現給定一個僅由小寫字母組成的字符串,你可以把它的字母重新排列,以形成不同的迴文字符串。
- 輸入:非空僅由小寫字母組成的字符串,長度不超過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;
}