基于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 ...
随机推荐
- 找一个数组的最大和的连续子数组(时间复杂度 O(n))(二)
要求: 要求数组从文件读取. 如果输入的数组很大, 并且有很多大的数字, 就会产生比较大的结果 (考虑一下数的溢出), 请保证你的程序能正常输出. 另外, 如果输入文件的参数有错误, 这个程序应该 ...
- CSS Sprite雪碧图
为了减少http请求数量,加速网页内容显示,很多网站的导航栏图标.登录框图片等,使用的并不是<image>标签,而是CSS Sprite雪碧图. 两个小例子: 淘宝首页的侧栏图 代码 &l ...
- js生成自定义随机数方法
function getRandom() { var chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', ...
- 适配iOS11
总结在iOS11系统中出现的适配问题: 启动app发现上下有空隙,不能完全贴合屏幕----- 解决方案:添加一张尺寸为1125x2436的启动图. 隐藏导航栏的界面,会出现无法贴合屏幕顶部(一般来说, ...
- CABaRet: Leveraging Recommendation Systems for Mobile Edge Caching
CABaRet:利用推荐系统进行移动边缘缓存 本文为SIGCOMM 2018 Workshop (Mobile Edge Communications, MECOMM)论文. 笔者翻译了该论文.由于时 ...
- 【机器学习】--线性回归中L1正则和L2正则
一.前述 L1正则,L2正则的出现原因是为了推广模型的泛化能力.相当于一个惩罚系数. 二.原理 L1正则:Lasso Regression L2正则:Ridge Regression 总结: 经验值 ...
- BBS论坛(二十三)
23.添加板块 (1)apps/models class BoardModel(db.Model): __tablename__ = 'board' id = db.Column(db.Integer ...
- Redis配置与安装
Redis 是一个非关系型高性能的key-value数据库.在部分场合可以对关系数据库起到很好的补充作用.它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C, ...
- 『最大M子段和 线性DP』
最大M子段和(51nod 1052) Description N个整数组成的序列a[1],a[2],a[3],-,a[n],将这N个数划分为互不相交的M个子段,并且这M个子段的和是最大的.如果M &g ...
- Linux~上部署.net MVC出现的问题与解决
这几天一直在搞linux下面的.net mvc的部署工作,遇到了很多问题,还好有一些朋友的帮助,问题才得到了解决! 环境:Linux+Mono+Jexus 希望的结果:直接运行windows+vist ...