迴文字符串

還是在龐果網看到的題目,這次選了個簡單的,迴文字符串。

題目內容


迴文字符串是指從左到右和從右到左相同的字符串,現給定一個僅由小寫字母組成的字符串,你可以把它的字母重新排列,以形成不同的迴文字符串。

  • 輸入:非空僅由小寫字母組成的字符串,長度不超過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;
	
}



四則運算和取模的字符串操作沒貼了,有點多而且不是算法核心,而且網上一大把,我也是網上找的,就不貼了。



發佈了54 篇原創文章 · 獲贊 16 · 訪問量 47萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章