基于C#程序设计语言的三种组合算法
基于C#程序设计语言的三种组合算法
1. 总体思路
1.1 前言
最近有个项目要求对多种材料进行装箱,我需要给出装箱的可能,这些材料进行过分组,每组中大致选取2-3个材料进行装箱。由于无法得知箱子大小(无法对组合数的m进行限制),材料会扩充,随之分组也会扩充(无法对组合数的n进行限制),所以理论上说能产生的组合是无限的,这当然无法实现,但我们还是能通过用户的输入来进行最大可能的处理。
1.2 算法思路
组合算法思路是比较简单的(以下所有数据都可以想象成string[]类型的),获取源数据S,C(1,n)的结果S1,将S的每个元素与S1进行相应组合得到C(2,n)的结果S2(思路演示见图1.2.1),S2,将S的每个元素与S2进行相应组合,得到S3...重复这个过程得到Sn。
S的元素与Si进行组合的方式不同获得的组合结果不同,如果和元素本身进行了组合,组合结果就包括了与自身组合。

图1.1 C(2, n)组合过程
1.3 算法需要注意的点
虽然思路比较简单,但是处理起来还是有些地方需要注意。在每次进行组合时,需要对Si进行去头处理。
去头处理:去掉Si中不能与S[i]组合的元素
在不同的组合中去掉的头也不同。在与S1组合时,每次去掉的只有一组元素[A],[B],[C],[D],[E],但在与S2组合时,去掉的头分别是:[A,B],[A,C],[A,D],[A,E](4组),[B,C],[B,D],[B,E](3组),[C,D],[C,E](2组),[D,E](1组)。推过推演可以发现,这组数据是有规律的,根据1.2,1.3小节总结出来的规律,大致可以构建出组合算法了。
2. 三种组合算法
2.1 普通组合算法
在第1章已经介绍了普通组合算法的思路,这里主要说明如何用C#代码来处理组合运算,首先需要定义三个List<string>类型src,res,tmp,src用来存储需要进行组合处理的源数据,res用来存储组合处理后的数据,tmp用来存储在操作过程中的临时数据。定义一个int[] rm变量用来存储每次需要去头的个数(例如src=[A,B,C,D,E],进行第一次组合时,rm = [1,1,1,1], 进行第二次组合时,rm = [4,3,2,1])。
string[] Combination(List<string> src, List<string> res, List<string> tmp, ref int[] rm, int rsp, int tmp_index, int rp)
{
if(res.Count() == 0)
{
return tmp;
}
if(rsp == res.Count())
{
src.Removerange(0, 1);
res.Removerange(0, rm[rp]);
rm[rp] = rsp;
rsp = 0;
rp += 1;
}
tmp[tmp_index] = src[0] + "," + res[rsp];
tmp = Combination(src, res, tmp, rm, rsp + 1, tmp_index + 1, rp);
return tmp;
}
代码清单2.1 普通组合算法
2.2 与自身进行组合的组合算法
本节思路及代码与2.1小节大同小异,故先略过。
2.3 组合元素进行过分组限制的组合算法
现在要求将元素进行分组,每组的元素个数随机,从每组最多选择x个元素进行组合。这种算法只需要在普通组合算法程序中进行一些条件限制便可以实现,最主要需要注意的问题是,rm中存储的数据不同了(对下次去掉的头有了限制)。由于rm[rp]不再是rsp了,所以需要新的变量count来计算下次需要去掉的头。
string[] Combination(List<string> src, List<string> res, List<string> tmp, ref int[] rm, int rsp, int tmp_index, int rp, int count)
{
if(res.Count() == 0)
{
return tmp;
}
if(rsp == res.Count())
{
src.Removerange(0, 1);
res.Removerange(0, rm[rp]);
rm[rp] = count;
rsp = 0;
rp += 1;
}
// ...
// 检测是否属于同一分组,如果属于同一分组,则bool bl = true;
// ...
if(bl == true)
tmp = Combination(src, res, tmp, rm, rsp + 1, tmp_index + 1, rp);
else
{
tmp[tmp_index] = src[0] + "," + res[rsp];
count++;
}
return tmp;
}
代码清单2.2 有分组限制的组合算法
代码清单2.2中,省略了“检测是否属于同一分组”的代码,因为不同需求的初始条件不一样,故略过了此段代码。在我涉及到的需求中,我是将分组内容用DataTable存储,然后“检测同一分组”时会去表中检索,以此来判断是否属于同一分组。对于检测,我将所需要检测的内容组合成一个数组,然后检测首元素是否与指向元素属于同一分组,如果属于,bool bl为true,如果不属于,则为false。
我将所需要检测的内容组合成一个数组,然后定义两个指针(索引)pa,pb,pa与pb初始都指向首元素,若pa内容与pb内容相等,则count++,若pa内容与pb内容不等,则pa = pb + 1,再重复上述步骤,这样可以统计出一个组内包含多少个成员。
3. 请使用循环替代递归
最后,请使用循环来带起递归过程,因为递归未结束时,是不会释放内存的,在数据量大时,会造成内存溢出的错误,所以,请使用循环。
PS: 本文所涉及的代码均未经过编译,若出现错误请进行修改。
基于C#程序设计语言的三种组合算法的更多相关文章
- js架构设计模式——你对MVC、MVP、MVVM 三种组合模式分别有什么样的理解?
你对MVC.MVP.MVVM 三种组合模式分别有什么样的理解? MVC(Model-View-Controller)MVP(Model-View-Presenter)MVVM(Model-View-V ...
- ASP.NET MVC:多语言的三种技术处理策略
ASP.NET MVC:多语言的三种技术处理策略 背景 本文介绍了多语言的三种技术处理策略,每种策略对应一种场景,这三种场景是: 多语言资源信息只被.NET使用. 多语言资源信息只被Javascrip ...
- 第二百五十九节,Tornado框架-模板语言的三种方式
Tornado框架-模板语言的三种方式 模板语言就是可以在html页面,接收逻辑处理的self.render()方法传输的变量,将数据渲染到对应的地方 一.接收值渲染 {{...}}接收self.re ...
- 排序—时间复杂度为O(n2)的三种排序算法
1 如何评价.分析一个排序算法? 很多语言.数据库都已经封装了关于排序算法的实现代码.所以我们学习排序算法目的更多的不是为了去实现这些代码,而是灵活的应用这些算法和解决更为复杂的问题,所以更重要的是学 ...
- FIFO、LRU、OPT这三种置换算法的缺页次数
考虑下述页面走向: 1,2,3,4,2,1,5,6,2,1,2,3,7,6,3,2,1,2,3,6 当内存块数量分别为3时,试问FIFO.LRU.OPT这三种置换算法的缺页次数各是多少? 答:缺页定义 ...
- 网络中,FIFO、LRU、OPT这三种置换算法的缺页次数
FIFO.LRU.OPT这三种置换算法的缺页次数 转载 由于要考计算机四级网络,这里遇到了问题,就搜了一些资料来解疑. 考虑下述页面走向: 1,2,3,4,2,1,5,6,2,1,2,3,7,6,3 ...
- 三种Hash算法对比以及秒传原理.
三种Hash算法对比以及秒传原理 CRC (32/64) MD5 Sha1 分5个点来说 1.校验值长度 2.校验值类别 3.安全级别 4.应用场景 1).校验值长度 CRC(32/64) 分别 ...
- 创建B树,动态添加节点,并使用三种遍历算法对树进行遍历
ks17:algorithm apple$ cat btree_test.c ///********************************************************** ...
- c++ 指针与const的三种组合
三种形式 const int a=1; int b=2: 1 const int * ptr1=&a; 2 int * const ptr2 = b; 3 const int * const ...
随机推荐
- 谨以此篇献给DJANGO学习过程中遇到的问题
谨以此篇献给DJANGO学习过程中遇到的问题 一.Django数据同步过程中遇到的问题: 1.raise ImproperlyConfigured('mysqlclient 1.3.13 or new ...
- 问题:这个新申请的内存为什么不能free掉?(已解决)
一.问题描述 先上代码, /*** 省略 ***/ uChar *base64 = NULL; /*** 省略 ***/ base64 = (一段内存) /*** 省略 ***/ base64 = s ...
- CSS文字的跑马灯特效
上学时同学有个来电带跑马灯的手机,可把我羡慕坏了,可等我买的起手机时,跑马灯不流行了,甚伤萝卜心! 今天就用CSS做个文字的跑马灯特效,缅怀一下本萝卜逝去的青春! 道具:会敲代码的巧手.七窍玲珑心.会 ...
- SQLite异常 qAdmin: Cannot perform this operation on a closed dataset.【申明:来源于网络】
SQLite异常 qAdmin: Cannot perform this operation on a closed dataset. 当使用 SQLite administrator,打开SQLit ...
- Java ActiveMQ 讲解(二)Spring ActiveMQ整合+注解消息监听
对于ActiveMQ消息的发送,原声的api操作繁琐,而且如果不进行二次封装,打开关闭会话以及各种创建操作也是够够的了.那么,Spring提供了一个很方便的去收发消息的框架,spring jms.整合 ...
- GT-随身调详细教程
一.GT介绍 GT(随身调)是APP的随身调测平台,它是直接运行在手机上的“集成调测环境”(IDTE, Integrated Debug Environment).利用GT,仅凭一部手机,无需连接电脑 ...
- [Swift]LeetCode852. 山脉数组的峰顶索引 | Peak Index in a Mountain Array
Let's call an array A a mountain if the following properties hold: A.length >= 3 There exists som ...
- [Swift]LeetCode881. 救生艇 | Boats to Save People
The i-th person has weight people[i], and each boat can carry a maximum weight of limit. Each boat c ...
- 白话说java gc垃圾回收
gc是java区别于其他好几门语言(c/c++)的一个代表功能(当然也有很多可以自动管理内存的语言,如所有的脚本语言,你根本不知道内存管理这回事)! 当然,之所以要把c/c++和java相比,是因为j ...
- Eclipse工具:常用快捷键记录
Eclipse快捷键: 按键操作 按键作用 输入sysout再按下Ctrl+Space System.out.println() Ctrl+1 当某行出错时时,跳出帮 ...