(1)字符串全排列 / 组合

题目描述:输入一个字符串,打印出该字符串的全部排列;

例如:字符串:abc     全排列:(abc , acb) , (bac , bca) , (cba , cab);

解题思路:

递归实现:从字符串中“依次”选择一个字符作为“首字符”,并在该“首字符”前提下,对剩余字符进行递归全排列处理;


“依次”:即始终在“初始字符串”的前提下,后面的字符分别于第一个字符交换;

字符串abc:

(abc)首字符a-->求剩余bc全排列:abc , acb;-->(a,b)交换-->bac;

(bac)首字符b-->求剩余ac全排列:bac , bca;-->(a,b)交换-->abc(以便在此基础上得到cba)-->(a,c)交换-->cba;

(cba)首字符c-->求剩余ba全排列:cba,cab;


算法递归实现:

#include<iostream>
using namespace std;
//------------------------------------------------------------------------------------------------------------------
void  Permutation(char* pStr , char* pBegin);
void  Swap(char *ch1 , char *ch2);
//-------------------------------------------------------------------------------------------------------------------
void  Swap(char *ch1 , char *ch2)
{
	char temp = *ch1;
	*ch1 = *ch2;
	*ch2 = temp;
}

//不能保证出现重复排列。
void Permutation(char* pStr , char* pBegin)
{
	if(*pBegin == '\0')
	{
		printf("%s\n" , pStr);
	}
	else
		for(char* pch = pBegin; *pch != '\0'; ++pch)
		{
                        Swap(pch , pBegin); 
			Permutation(pStr , pBegin + 1);
			Swap(pch , pBegin);
		}
}

void Permutation(char* pStr)
{
	if(pStr == NULL)
		return ;

	Permutation(pStr , pStr);
}

但是若字符串中出现重复的字符,两者交换。全排列中会出现重复的结果。这样不仅加大工作量,而且还是没有意义的,故应该去掉重复的全排列结果。

怎么去除呢?

规则:从首字符起,每个字符依次与后面不重复的字符交换。

例子:字符串abb;

(abb)首字符a-->求剩余全排列:abb-->(b,b)相等不交换;-->(a,b)交换bab;

(bab)首字符b-->求剩余全排列:bab , bba;-->(b,a)交换abb-->由于二三字符b ,b 相同,故a不再与第三个字符交换,结束;

代码实现:

#include<iostream>  
using namespace std;  
//------------------------------------------------------------------------------------------------------------------------
bool IsSwap(char* pBegin , char* pEnd);           //判断是否有字符相等
void Permutation(char* pStr , char *pBegin);
//------------------------------------------------------------------------------------------------------------------------
void Permutation(char* pStr)
{
	if(!pStr)
		return;

	Permutation(pStr , pStr);
}
  
//在[nBegin,nEnd)区间中是否有字符与下标为pEnd的字符相等  
bool IsSwaped(char* pBegin , char* pEnd)  
{  
    char *S;  
    for(S = pBegin ; S < pEnd ; S++)  
    {  
        if(*S == *pEnd)  
            return false;  
    }  
    return true;  
}  

void Permutation(char* pStr , char *pBegin)  
{  
  
    if(*pBegin == '\0')  
    {  
        printf("%s\n",pStr);  
    }  
    else  
    {  
	  //依次与首字符交换,固定。剩余递归进行全排列
        for(char *pCh = pBegin; *pCh != '\0'; pCh++)  
        {  
            if(IsSwaped(pBegin , pCh))  
            {  
                swap(*pBegin , *pCh);  
                Permutation(pStr , pBegin + 1);  
                swap(*pBegin , *pCh);  
            }  
        }  
    }  
}  


字符串的组合问题:

问题描述:给定一个字符串,求该字符串中所有字符的组合;例如abc,所求组合为:a , b , c , ab , ac , bc , abc;


长度为n的字符串,选取m个字符的组合,其中1 <= m <= n;

设总组合数为Comb(n , m) = Comb(n , 1) + Comb(n , 2) + Comb(n , 3) + ......+ Comb(n , n);

递归求解

从首字符开始扫描,若被选中,则递归求解:Comb(n - 1 , m - 1);

                                 若未被选中,则递归求解:Comb(n - 1 , m);

递归终止条件: n = 0  或者  m = 0;


代码实现:

#include<iostream>
#include<vector>
#include<cstring>
using namespace std;
//------------------------------------------------------------------------------------------------------------------
void Combination(char* pStr , int m , vector<char>& result);
//-------------------------------------------------------------------------------------------------------------------
//函数功能:求一个字符串的所有组合
//参数:字符串pStr
void Combination(char* pStr)
{
	if(pStr == NULL)
		return;

	vector<char> result;
      int length = strlen(pStr);

	for(int i = 1; i <= length; i++)
		Combination(pStr , i , result);
}

//函数功能:从一个字符串中选取m个字符
//参数:字符串pStr ,选取元素个数m , 存放结果result
void Combination(char* pStr , int m , vector<char>& result)
{
	if(pStr == NULL || (*pStr == '\0' && m != 0))
		return;

	//递归终止条件
	if(m == 0)
	{
		vector<char>::iterator  iter = result.begin();
		for( ; iter != result.end(); iter++)
			cout<<*iter<<' ';
		cout<<endl;

		return;     //注意
	}

	//选中此元素
	result.push_back(*pStr);
	Combination(pStr + 1 , m - 1 , result);
	result.pop_back();

	//未选中此元素
	Combination(pStr + 1 , m , result);

}

//----------------------------------------------------------------------------------------------------------------
int main()
{
	char string1 [] = " ";
      Combination(string1);

	char string2[] = "accd";
	Combination(string2);

	return 0 ;
}








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
字符串的排列是指对给定的字符串进行全排列,即将字符串中的字符重新排列,找出所有可能的排列组合。 如果给定的字符串是空字符串或者长度为1的字符串,那么它的排列只有它自身。 对于长度大于等于2的字符串,可以通过递归的方式来进行排列。可以将字符串分为两部分,第一个字符和剩下的字符。首先固定第一个字符,然后对剩下的字符进行全排列。接着固定第二个字符,对剩下的字符进行全排列,以此类推。 具体的实现可以采用回溯法,通过递归和交换字符的方式,依次固定每个字符,然后对剩下的字符进行全排列。当递归到最后一个字符时,就得到了一个完整的排列。将每个完整的排列添加到结果集中。 下面是一个使用递归实现字符串排列的示例代码: ```java import java.util.ArrayList; import java.util.List; public class StringPermutation { public List<String> getPermutation(String str) { List<String> result = new ArrayList<>(); if (str == null || str.length() == 0) { return result; } permutation(str.toCharArray(), 0, result); return result; } private void permutation(char[] chars, int start, List<String> result) { if (start == chars.length - 1) { result.add(String.valueOf(chars)); } else { for (int i = start; i < chars.length; i++) { swap(chars, start, i); permutation(chars, start + 1, result); swap(chars, start, i); } } } private void swap(char[] chars, int i, int j) { char temp = chars[i]; chars[i] = chars[j]; chars[j] = temp; } } ``` 以上代码实现了一个`getPermutation`方法,该方法将给定的字符串进行排列,并将结果存储在一个列表中。方法中使用递归和交换字符的方式来实现排列。最终返回的结果是一个包含所有排列的字符串列表。 使用该方法可以对任意字符串进行排列,如:"abc"的全排列为["abc", "acb", "bac", "bca", "cab", "cba"]。 总结就是,字符串的排列可以通过递归和交换字符的方式来实现,找出所有可能的排列组合。以上就是一个使用Java实现字符串排列的示例代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值