基于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>类型srcrestmpsrc用来存储需要进行组合处理的源数据,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 bltrue,如果不属于,则为false

我将所需要检测的内容组合成一个数组,然后定义两个指针(索引)papbpapb初始都指向首元素,若pa内容与pb内容相等,则count++,若pa内容与pb内容不等,则pa = pb + 1,再重复上述步骤,这样可以统计出一个组内包含多少个成员。

3. 请使用循环替代递归

最后,请使用循环来带起递归过程,因为递归未结束时,是不会释放内存的,在数据量大时,会造成内存溢出的错误,所以,请使用循环。

PS: 本文所涉及的代码均未经过编译,若出现错误请进行修改。

基于C#程序设计语言的三种组合算法的更多相关文章

  1. js架构设计模式——你对MVC、MVP、MVVM 三种组合模式分别有什么样的理解?

    你对MVC.MVP.MVVM 三种组合模式分别有什么样的理解? MVC(Model-View-Controller)MVP(Model-View-Presenter)MVVM(Model-View-V ...

  2. ASP.NET MVC:多语言的三种技术处理策略

    ASP.NET MVC:多语言的三种技术处理策略 背景 本文介绍了多语言的三种技术处理策略,每种策略对应一种场景,这三种场景是: 多语言资源信息只被.NET使用. 多语言资源信息只被Javascrip ...

  3. 第二百五十九节,Tornado框架-模板语言的三种方式

    Tornado框架-模板语言的三种方式 模板语言就是可以在html页面,接收逻辑处理的self.render()方法传输的变量,将数据渲染到对应的地方 一.接收值渲染 {{...}}接收self.re ...

  4. 排序—时间复杂度为O(n2)的三种排序算法

    1 如何评价.分析一个排序算法? 很多语言.数据库都已经封装了关于排序算法的实现代码.所以我们学习排序算法目的更多的不是为了去实现这些代码,而是灵活的应用这些算法和解决更为复杂的问题,所以更重要的是学 ...

  5. 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这三种置换算法的缺页次数各是多少? 答:缺页定义 ...

  6. 网络中,FIFO、LRU、OPT这三种置换算法的缺页次数

    FIFO.LRU.OPT这三种置换算法的缺页次数 转载  由于要考计算机四级网络,这里遇到了问题,就搜了一些资料来解疑. 考虑下述页面走向: 1,2,3,4,2,1,5,6,2,1,2,3,7,6,3 ...

  7. 三种Hash算法对比以及秒传原理.

    三种Hash算法对比以及秒传原理 CRC (32/64)   MD5  Sha1 分5个点来说 1.校验值长度 2.校验值类别 3.安全级别 4.应用场景 1).校验值长度 CRC(32/64) 分别 ...

  8. 创建B树,动态添加节点,并使用三种遍历算法对树进行遍历

    ks17:algorithm apple$ cat btree_test.c ///********************************************************** ...

  9. c++ 指针与const的三种组合

    三种形式 const int a=1; int b=2: 1 const int * ptr1=&a; 2  int * const ptr2 = b; 3 const int * const ...

随机推荐

  1. laravel-神奇的服务容器(转)

    原文地址: http://www.insp.top/learn-laravel-container ,转载务必保留来源,谢谢了! 容器,字面上理解就是装东西的东西.常见的变量.对象属性等都可以算是容器 ...

  2. 用 PHP文件引入css样式

    html: <link rel="stylesheet" type="text/css" href="http://www.mysite.com ...

  3. 小甲鱼Python3笔记

    000-愉快的开始 入门容易,学习难,代码量少. 跨平台: Windows, Mac OS, Linux, UNIX. 应用领域: 操作系统 WEB 3D动画 企业应用 云计算等等. 001-我和Py ...

  4. java实现多线程使用多个代理ip的方式爬取网页页面内容

    项目的目录结构 核心源码: package cn.edu.zyt.spider; import java.io.BufferedInputStream; import java.io.FileInpu ...

  5. Linux指令 压缩与解压

    打包: 格式:tar -cvf  压缩后的名称.tar   压缩的文件1 压缩的文件2 ```压缩的文件n(压缩多个文件为一份时各个文件以空格隔开) 例子:tar -cvf  tomcats.tar ...

  6. 1.7 All components require plug-in?

    In Android, Activity, Service, ContentProvider, and BroadcastReceiver are called as four major compo ...

  7. nginx+letsencrypt搭建https站点

    1. 申请好自己的域名 dockerhub.xxx.com,并解析好IP. 2. 安装nginx(默认开通了http) ,修改 server_name dockerhub.xxxx.com; 启动. ...

  8. S-CMS企建v3二次SQL注入

    S-CMS企建v3二次SQL注入 0x01 前言 继上一篇的S-CMS漏洞再来一波!首发T00ls 0x2 目录 Sql注入二次SQL注入 0x03 Sql注入 漏洞文件:\scms\bbs\bbs. ...

  9. [Swift]LeetCode4. 两个排序数组的中位数 | Median of Two Sorted Arrays

    There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two ...

  10. [Swift]LeetCode441. 排列硬币 | Arranging Coins

    You have a total of n coins that you want to form in a staircase shape, where every k-th row must ha ...