关于全排列的递归算法和非递归算法及内存优化
来源:互联网 发布:mac提取dsdt 编辑:程序博客网 时间:2024/06/04 08:57
- 这位博友的发贴
- leeyon415
- string[] m_Data={"我","是","好","人"},
这里的 数组长度不一定4个,可能 10个 100个
我要返回所有 不重复 组合!如:
{"我","是","好","人"},
{"我","好","是","人"},
{"我","人","是","好"},
{"是","好","人","我"},
{"好","人","我","是"},
{"人","我","是","好"},
...
..
我的回复是(加上了注释):
#region MyRegion 递归
List<List<string>> GetAll(List<string> lst) {
List<List<string>> lstRet = new List<List<string>>();
if (lst == null || lst.Count < 2) {
lstRet.Add(lst);
return lstRet;
}
//只处理不小于2的情况
List<string> a = lst.GetRange(0, lst.Count - 1);
string b = lst[lst.Count - 1];
lstRet.Add(a);
if (a.Count == 1) return GetAtom(lstRet, b);
List<List<string>> temp = GetAll(a);
return GetAtom(temp, b);
}
//得到基础排列的组合,最基本的是从两个元素开始的。
//
List<List<string>> GetAtom(List<List<string>> lst,string b){
List<List<string>> lstRet = new List<List<string>>();
if (lst == null) return lst;
foreach (List<string> sub in lst) {
for(int i = 0; i < sub.Count + 1;i++){
List<string> temp = new List<string>();
temp.AddRange(sub);
temp.Insert(i,b);
lstRet.Add(temp);
}
}
return lstRet;
}
#endregion
下边的是调用 的代码,
private void button1_Click(object sender, EventArgs e) {
//init ,这是Demo数据,生成了10个数字,你可以调大一点,
//不要太大哟,太大了堆栈会溢出
List<string> lst = new List<string>(100);
for (int i = 0; i < 10; i++) {
lst.Add(i.ToString());
}
//返回值就是所有的组合,每个元素是List<string>,表示一种组合
//
List<List<string>> lstRet = this.GetN(lst);
//这是输出结果的过程,
if (lstRet == null) return;
foreach (List<string> sub in lstRet) {
if (sub == null || sub.Count == 0) continue;
string sAll = "";
foreach (string ss in sub) {
sAll += "," + ss;
}
Debug(sAll);
}
}
//这里输出结果,随便 在窗体上加个 ListBox
void Debug(string s) {
listBox1.Items.Add(s);
}
这个程序用递归实现,相当耗费资源(试下100个元素,但是,代码很简洁,不包括调用,稍改一下,20句代码应该可以搞定。
暂时还没有时间改非递归,非递归也比较简单,就是递推。 用递推对资源的占用应该比较少。
以下是今天改过的非递归算法:
这是非递归编写的代码,也比较简单,原理和递归有相似之处。
从两个数的组合开始,递推到N个数。
#region MyRegion 递推
List<List<string>> DoGetAll(List<string> lst) {
List<List<string>> lstRet = new List<List<string>>();
if (lst == null || lst.Count < 2) {
lstRet.Add(lst);
return lstRet;
}
List<List<string>> temp = new List<List<string>>();
for (int i = 0; i < lst.Count - 1; i++) {
List<string> a = lst.GetRange(0, i + 1);
string b = lst[i + 1];
if (i == 0) temp.Add(a);
temp = DoGetAtom(temp, b);
}
return temp;
}
List<List<string>> DoGetAtom(List<List<string>> lst,string b){
List<List<string>> lstRet = new List<List<string>>();
if (lst == null) return lst;
foreach (List<string> sub in lst) {
for(int i = 0; i < sub.Count + 1;i++){
List<string> temp = new List<string>();
temp.AddRange(sub);
temp.Insert(i,b);
lstRet.Add(temp);
}
}
return lstRet;
}
#endregion
以上代码其实有个深层次的问题,就是事实上它能计算的数据的范围是极其有限的。
如果解决大量集合的排列问题呢?
有很多方案,无法是以下几类:
(1)把内存装不下的数据移到外存中来处理
(2)分段处理,分而治之。
(3)1,2的结合。
其实,以上程序,只需要把 保存结果 的部分独立出来,单独做成一个数据结构(这个结构中存入的数据不受4G限制,事实上链表就可以),就可以解决本程序 的问题。
从执行效率上来看,这个程序是无法保证效率的。 可以对string, list进行优化,在大数量据时提高性能。
- 关于全排列的递归算法和非递归算法及内存优化
- 关于全排列的递归和非递归算法
- 全排列非递归算法
- 全排列的非递归算法
- 全排列的非递归算法
- 全排列算法的非递归实现
- 全排列算法非递归实现和递归实现
- 全排列算法非递归实现和递归实现
- 全排列算法非递归实现和递归实现
- 全排列算法的递归与非递归实现
- 全排列算法的递归与非递归实现
- 全排列算法的递归与非递归实现
- 全排列的递归与非递归算法实现
- 全排列算法--一种非递归算法的实现
- C#:通过递归和非递归算法实现按顺序输出的全排列
- 字符串的全排列和组合算法(递归非递归)
- 全排列的递归算法
- 全排列的递归算法
- pic 开发的一个小实验全过程程
- 在DLL中使用资源
- 牛刀小试 JAVA内置 观察者模式
- 很忙很忙编程和论坛
- 用CreateToolhelp32Snapshot/Process32First/Process32Next API枚举系统进程
- 关于全排列的递归算法和非递归算法及内存优化
- ldd3 读书笔记 —— Hello, world!
- Java String的再研究
- 启动代码和Bootloader的区别
- Ubuntu
- 好
- 第一天
- 无痕~
- 不错的网站论坛