给一个字符串(包含重复字符),打印它的所有可能的组合。
来源:互联网 发布:chart.js x轴太挤 编辑:程序博客网 时间:2024/05/21 11:58
这是一个很老的题目,从我大学毕业开始找工作就碰到它了,但真正能正确编出它的人却很少。而网上搜来的代码,不是错误,就是思维不够清晰。就我自己而言,一时写对,时间一长再写它,就错误多多,现在我就来总结一下,和大家分享一下编成的快乐!
首先我们来说一下这个问题的基本算法,其实很简单,是一个典型的递归算法:
假设给定的字符串是 babc ([]中的为下一次递归的输入):
1. abbc 排序: 让相等的字符连续
2. a[bbc] 求解以第一个字符开头的组合
|
3. b[abc] 发现第二个字符b和上一组组合的头a 不相等,所以调换,并求解一新头(b) 开头的组合
4. abbc 还原上一次的交换
|
5. abbc b和第3步中的第一个字符b相等跳过(以b开头的组合已经在第3步中求解了)
|
6. c[bba] c和上一组组合的头(b) 不相等,所以调换,并求解一新头(c)开头的组合
以下是我整理的源码(注释和上面的算法对应):
class Program
{
static void Main(string[] args)
{
permutation("babc");
}
static void permutation(string input)
{
char[] temp = input.ToCharArray();
//abbc 排序: 让相等的字符连续
Array.Sort(temp);
SubPermutation(temp, 0);
Console.WriteLine(count);
}
//用来记录共有多少种组合
static int count = 0;
//start是剩余字符串的第一个字符的位置
static void SubPermutation(char[] input, int start)
{
if (start == input.Length-1)
{
//递归出口,即需要求的字符为最后一个字符
foreach (char c in input)
{
Console.Write(c + " ");
}
Console.WriteLine();
count++;
}
else
{
char head = input[start];
for (int i = start; i < input.Length; ++i)
{
if (i == start)
{
//求解以第一个字符开头的组合
SubPermutation(input, start + 1);
}
else
{
if (input[i] != head)
{
//b[abc] 发现第二个字符b和上一组组合的头a 不相等,所以调换.
//exchange
char temp = input[start];
input[start] = input[i];
input[i] = temp;
//update head to current head.
head = input[start];
//并求解一新头(b) 开头的组合
//deal with left item.
SubPermutation(input, start + 1);
//还原上一次的交换
//exchange
temp = input[start];
input[start] = input[i];
input[i] = temp;
}
// b和第3步中的第一个字符b相等跳过(以b开头的组合已经在第3步中求解了)
}
}
}
}
}
- 给一个字符串(包含重复字符),打印它的所有可能的组合。
- 找出一个字符数组(元素不重复)所有可能字符的组合
- 读取一个字符串,输出它里面字符的所有组合
- 打印一个字符串中字符的所有组合
- 已知一个字符串,输出它包含字符的所有排列(permutations)
- 编程列出一个字符串的全字符组合情况,原始字符串中没有重复字符,例如: 原始字符串是"abc",打印得到下列所有组合情况
- 读取一个字符串,并输出它里面字符的所有组合
- 已知一个有重复字符的字符串,打印其所有不同的字符排列
- 打印所有字母所有可能的组合
- 打印出大小为n的数组(可能有重复元素)里所有可能的组合
- 输出字符串所有组合(含有重复的字符)及输出其所有子串(含有重复的字符)
- 给定一个可能包含重复的整数的集合,S返回所有可能的子集。
- 打印出所有可能的括号组合
- 按要求打印字符数组中所有可能的字符组合
- 一个字符串中包含另一个字符串所有字符的最短子串
- 哈希表:一个字符串是否包含另一个字符串的所有字符
- 打印出一个字符串的所有组合的递归方式
- 给定一个集合(字符数组),打印出它的所有子集
- VIM正则表达式替换
- 代理类的具体例子(1接口【Advice】)
- exchange2010中批量外部邮件联系人导入
- Hibernate 学习总结
- Win7 下VPN使用和网讯网卡使用
- 给一个字符串(包含重复字符),打印它的所有可能的组合。
- Flex2 国际化(internationalization)
- 纵容客户
- The type java.lang.Object cannot be resolved解决方法 Z转
- sql 求字段类型
- windows笔记
- 在Delphi程序中操作注册表(转)
- mysql基本连接,mysqli,pdo,adodb,pearDB之间的区别,速度测试
- 异常处理