zoukankan      html  css  js  c++  java
  • 回文字符串

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

    题目内容


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

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



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



  • 相关阅读:
    <<剪绳子>>题解
    P5743 小猴吃桃 题解
    注意C++中的int与long long 的乘法
    数组初始化方法总结
    一维差分和二维差分
    一维前缀和与二维前缀和
    例2-6 字母转换
    例1-11 评测机队列
    golang ---查找字串实例 IP address
    mongodb ---加减等操作
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3212479.html
Copyright © 2011-2022 走看看