给定一个字符串,输出其所有的可能排列

本文详细介绍了如何使用递归方法生成一个给定字符串的所有排列,并提供了C/C++代码实现,包括解决重复字符的问题及解释了char*与char[]定义的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载请注明来自souldak,微博:@evagle

Question:

给你一个字符串例如abb输出它包含的字符的所有可能排列。

例如abb输出3个:abb,bab,bba

Answer:

假设我们自己来做,那做法如下:

1. 有n个字符相当于n个格子。

2. 先放第一个格子,从n个字符中任选一个,放到这个格子即可,放完就剩下n-1个格子和n-1个字符

3. 放第二个格子,从n-1个字符中任选一个

。。。

n. 最后一个格子,只剩下一个字符,不用选,输出放好的结果


第二步到第n步其实问题本质是一样的,k个字符选一个,放到格子里即可。problem与subproblem的关系,所以我们可以用递归求解。

1. 获得字符串s,得到长度n

2. 轮询确定s[0]放哪个字符,共有n个,如果放第k个,就把s[k]放到s[0],s[0]放到s[k]

3. 放好后就求解子问题,即求s[1]~s[n-1]的排列

4. 如果已经求解到s[n-1],输出结果


Attention:传入的str应该是char数组,不能是这样定义的:char* str = "abc"; 具体为什么请参看:C/C++中char* 与char []定义的区别

//rm_dup: true for remove duplicated strings
void permutation(char* str, int start, bool rm_dup){
    if(str==NULL||str=="")
        return;
    if(start==strlen(str)-1)
        cout<<str<<endl;
    bool visit[256];
    memset(visit,0,sizeof(visit));
    for(int i=start;i<strlen(str);i++){
        if(!visit[str[i]]||!rm_dup){
            visit[str[i]] = true;
            std::swap(str[start],str[i]);
            permutation(str,start+1,rm_dup);
            std::swap(str[start],str[i]);
        }   
    }   
}


### 实现字符串排列算法 对于字符串的全排列问题,可以采用递归的方式解决。当处理较短的字符串时,这种方法效率较高且易于理解。下面是一个基于C#语言的具体实现方案[^1]。 #### 使用C#编写全排列函数 定义名为`PermuteString`的方法来接收两个参数:一个是待处理的字符串`s`;另一个是指向当前正在构建的新排列起始位置的索引`startIdx`。每当完成一次完整的字符重排后,就将新形成的字符串加入最终的结果集合中。为了防止重复计算已经访问过的元素,在交换字符之前先检查是否越界以及是否存在相同字符的情况。 ```csharp using System; using System.Collections.Generic; public class StringPermutation { public static List<string> Permutations(string s) { var result = new List<string>(); if (string.IsNullOrEmpty(s)) return result; char[] chars = s.ToCharArray(); Generate(0, chars, ref result); return result; } private static void Generate(int startIdx, char[] array, ref List<string> list){ if(startIdx >= array.Length - 1){ string str = new string(array); if(!list.Contains(str)){ list.Add(new string(array)); } return ; }else{ for(int i=startIdx;i<array.Length;++i){ Swap(ref array[startIdx],ref array[i]); Generate(startIdx+1,array,ref list); Swap(ref array[startIdx],ref array[i]); // backtrack } } } private static void Swap<T>(ref T a, ref T b){ T temp=a;a=b;b=temp; } } ``` 此代码片段实现了对输入字符串的所有不同排列形式进行枚举的功能,并将其存储在一个列表里以便后续操作或展示给用户查看[^4]。 #### 关于性能考量 值得注意的是,由于涉及到大量的分支结构和回溯过程,因此该算法的时间复杂度为O(n!),其中n代表原始字符串中的字符数量。这意味着随着输入规模的增长,执行所需时间和资源也会呈指数级增加。不过考虑到题目限定条件(即字符串长度小于等于9),这样的解决方案仍然是可行并有效的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值