回文字符串

还是在庞果网看到的题目,这次选了个简单的,回文字符串。

题目内容


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

  • 输入:非空仅由小写字母组成的字符串,长度不超过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;
	
}



四则运算和取模的字符串操作没贴了,有点多而且不是算法核心,而且网上一大把,我也是网上找的,就不贴了。



原文地址:https://www.cnblogs.com/jiangu66/p/3212479.html