返回 n 中 k 个元素的所有组合的算法

2023-12-11

我想编写一个函数,它接受一个字母数组作为参数,并选择其中的一些字母。

假设您提供一个包含 8 个字母的数组,并希望从中选择 3 个字母。那么你应该得到:

8! / ((8 - 3)! * 3!) = 56

返回数组(或单词),每个数组由 3 个字母组成。


计算机编程艺术第 4 卷:分册 3有很多可能比我描述的更适合您的特定情况。

格雷码

An issue that you will come across is of course memory and pretty quickly, you'll have problems by 20 elements in your set -- 20C3 = 1140. And if you want to iterate over the set it's best to use a modified gray code algorithm so you aren't holding all of them in memory. These generate the next combination from the previous and avoid repetitions. There are many of these for different uses. Do we want to maximize the differences between successive combinations? minimize? et cetera.

一些描述格雷码的原始论文:

  1. 一些汉密尔顿路径和最小变化算法
  2. 相邻立交组合生成算法

以下是涉及该主题的其他一些论文:

  1. Eades、Hickey、Read相邻互换组合生成算法的高效实现(PDF,带有 Pascal 代码)
  2. 组合发电机
  3. 组合格雷码综述(后记)
  4. 格雷码算法

蔡斯的旋转(算法)

菲利普·J·蔡斯,`算法 382:N 个对象中 M 个的组合' (1970)

C 语言的算法...

字典顺序组合索引(Buckles 算法 515)

您还可以通过索引(按字典顺序)引用组合。意识到索引应该是基于索引从右到左的一些变化,我们可以构造一些应该恢复组合的东西。

所以,我们有一个集合 {1,2,3,4,5,6}...并且我们需要三个元素。假设{1,2,3},我们可以说元素之间的差异为一,并且按顺序且最小。 {1,2,4} 有一个更改,按字典顺序排列为 2。因此,最后一位的“更改”数量说明了字典顺序中的一个更改。第二个位置,有一项更改 {1,3,4} 有一项更改,但由于它位于第二位(与原始集合中的元素数量成比例),因此造成了更多更改。

我所描述的方法是一种解构,看起来,从集合到索引,我们需要做相反的事情——这要棘手得多。就是这样Buckles解决了问题。我写了一些C 来计算它们,有一些细微的变化——我使用集合的索引而不是数字范围来表示集合,所以我们总是从 0...n 开始工作。 笔记:

  1. 由于组合是无序的,{1,3,2} = {1,2,3}——我们按字典顺序对它们进行排序。
  2. 此方法有一个隐式 0 来启动第一个差异的集合。

字典顺序组合索引 (McCaffrey)

其他方式:,它的概念更容易掌握和编程,但没有 Buckles 的优化。幸运的是,它也不会产生重复的组合:

The set x_k...x_1 in N that maximizes i = C(x_1,k) + C(x_2,k-1) + ... + C(x_k,1), where C(n,r) = {n choose r}.

举个例子:27 = C(6,4) + C(5,3) + C(2,2) + C(1,1)。因此,第 27 个四项的字典组合是:{1,2,5,6},这些是您想要查看的任何集合的索引。下面的示例(OCaml),需要choose函数,留给读者:

(* this will find the [x] combination of a [set] list when taking [k] elements *)
let combination_maccaffery set k x =
    (* maximize function -- maximize a that is aCb              *)
    (* return largest c where c < i and choose(c,i) <= z        *)
    let rec maximize a b x =
        if (choose a b ) <= x then a else maximize (a-1) b x
    in
    let rec iterate n x i = match i with
        | 0 -> []
        | i ->
            let max = maximize n i x in
            max :: iterate n (x - (choose max i)) (i-1)
    in
    if x < 0 then failwith "errors" else
    let idxs =  iterate (List.length set) x k in
    List.map (List.nth set) (List.sort (-) idxs)

一个小而简单的组合迭代器

The following two algorithms are provided for didactic purposes. They implement an iterator and (a more general) folder overall combinations. They are as fast as possible, having the complexity O(nCk). The memory consumption is bound by k.

我们将从迭代器开始,它将为每个组合调用用户提供的函数

let iter_combs n k f =
  let rec iter v s j =
    if j = k then f v
    else for i = s to n - 1 do iter (i::v) (i+1) (j+1) done in
  iter [] 0 0

更通用的版本将从初始状态开始调用用户提供的函数以及状态变量。由于我们需要在不同状态之间传递状态,因此我们不会使用 for 循环,而是使用递归,

let fold_combs n k f x =
  let rec loop i s c x =
    if i < n then
      loop (i+1) s c @@
      let c = i::c and s = s + 1 and i = i + 1 in
      if s < k then loop i s c x else f c x
    else x in
  loop 0 0 [] x
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

返回 n 中 k 个元素的所有组合的算法 的相关文章

  • 寻找距离原点最近的 100 颗恒星的算法

    首先让我提出正确的问题 问 有一个文件包含超过一百万个点 x y 每个点代表一颗星星 a b 处有一颗行星地球 现在 任务是构建一种算法 返回距离地球最近的 100 颗恒星 您的算法的时间和空间复杂度是多少 这个问题在各种采访中被问过很多次
  • 如何将一组重叠范围划分为不重叠范围?

    假设您有一组范围 0 100 一 0 75 b 95 150 c 120 130 d 显然 这些范围在某些点上重叠 您将如何剖析这些范围以生成不重叠范围的列表 同时保留与其原始范围相关的信息 在本例中为范围后面的字母 例如 运行算法后的上述
  • 找到一系列间隔的最有效分组

    我有一个应用程序 其中有一系列不重叠的固定宽度间隔 每个间隔都有一个给定的键 每个间隔具有相同的宽度 并且可以存在连续的间隔 本质上 我想以最小化单独间隔的数量的方式对间隔和键进行分组 这可以通过合并具有相同键的连续间隔或查找匹配间隔并将它
  • 点集子集的最小周长凸包

    给定平面上的 n 个点 没有 3 个共线 给定数字 k 找到 k 个点的子集 使得 k 个点的凸包在 k 个点的子集的任何凸包中具有最小周长 我可以想到一个简单的方法 运行时间为 O n k k log k 找到大小为 k 的每个子集的凸包
  • Karasuba算法递归过多

    我正在尝试用 c 实现 Karasuba 乘法算法 但现在我只是想让它在 python 中工作 这是我的代码 def mult x y b m if max x y lt b return x y bm pow b m x0 x bm x1
  • 从三点求圆心的算法是什么?

    我在圆的圆周上有三个点 pt A A x A y pt B B x B y pt C C x C y 如何计算圆心 在Processing Java 中实现它 我找到了答案并实施了一个可行的解决方案 pt circleCenter pt A
  • 数组中连续元素的最大乘积

    我在现场面试的时候被问到了这个算法问题 由于没有要求我签署保密协议 我将其发布在这里寻求答案 给定一个数组REAL不包含 0 的数字 找到产生最大乘积的连续元素 该算法应在线性时间内运行 我考虑过以下方法 使用两个数组 第一个是利用DP思想
  • URL路径相似度/字符串相似度算法

    我的问题是我需要比较 URL 路径并推断它们是否相似 下面我提供了要处理的示例数据 GROUP 1 robots txt GROUP 2 bot html GROUP 3 phpMyAdmin 2 5 6 rc1 scripts setup
  • C 埃及分数

    古埃及人仅使用以下形式的分数1 n因此任何其他分数都必须表示为这些单位分数的总和 而且 所有单位分数都是不同的 在C或Java中使任何分数成为埃及分数 总和越少越好 的好方法是什么 可以使用什么算法 分支定界 a 例如 3 4 1 2 1
  • 包围一组点的多边形

    我有一组 S 点 2D 由 x 和 y 定义 我想找到 P 包围该组所有点的最小 含义 具有最少数量的点 多边形 P 是S 有没有已知的算法来计算这个 我在这个领域缺乏文化令人惊讶 感谢您的帮助 对于这个问题有很多算法 它被称为 最小边界框
  • 快速约会算法

    我在一家咨询公司工作 大部分时间都在客户所在地 正因为如此 我很少见到同事 为了更好地了解彼此 我们将安排一个晚宴 会有很多小桌子 方便人们聊天 为了在聚会期间与尽可能多的不同的人交谈 每个人都必须每隔一段时间 比如每小时 换一张桌子 如何
  • 使用多级解决方案计算二维网格中的最近邻

    我有一个问题 在 x y 大小的网格中 我提供了一个点 并且我需要找到最近的邻居 在实践中 我试图在 pygame 中找到距离光标最近的点 该点跨越颜色距离阈值 计算如下 sqrt rgb1 0 rgb2 0 2 rgb1 1 rgb2 1
  • 如何有效地找到距给定点最远的点(从一组点中)?

    我正在寻找一种算法或数据结构来解决以下问题 给你一组点 S 然后你会得到另一个点形式的 Q 查询 对于每个查询 找到集合中距离给定点最远的点 集合中最多有 10 5 个点和 10 5 个查询 所有点的坐标都在 0 到 10 5 范围内 我想
  • shell脚本中关联数组的时间复杂度

    我想知道在 shell 脚本中使用关联数组时如何构造 实现 另外 我想知道基于 shell 脚本的关联数组的时间复杂度是否是最佳的 因为我们可以使用字母和数字作为它们各自的键 编辑 他们使用什么哈希函数 如果您使用关联数组 则不能通过 使用
  • 举例解释bpe(字节对编码)?

    有人可以帮忙解释一下背后的基本概念吗BPE模型 除了这张纸 https arxiv org abs 1508 07909 目前还没有那么多解释 到目前为止我所知道的是 它通过将罕见和未知的单词编码为子词单元序列来实现开放词汇表上的 NMT
  • 在java中使用BUBBLE SORT对二维字符串数组进行排序

    类似的问题已经被问过 但从来没有关于二维字符串数组 因此在尝试了很长时间之后我找不到我想要的 我正在尝试使用 BubbleSort 对 java 中的 2D 字符串数组进行排序 作为输入 我收到一个二维字符串数组 一个表 以及您应该排序的
  • 有没有时间复杂度为O(N)的排序算法?

    大多数排序算法的复杂度为 O NN 或 O NlogN 来实现结果 但是 对于特定的输入集 有些算法的复杂度为 O N 我想知道是否有一种排序算法在所有情况下都具有 O N 的复杂度 如果您只能比较 检查两个项目是否为 正在排序的值 那么您
  • 如何对对象进行排序? (画家算法)

    所以我有 4 个矩形形状 我正在尝试应用排序算法 画家算法 https en wikipedia org wiki Painter 27s algorithm 来知道我需要先绘制哪些形状 在 3d 中 然后绘制哪个形状 Note 相机位于右
  • 数学/算法使图像适合屏幕保留纵横比

    我需要数学 算法方面的帮助来拍摄已知尺寸的图像并适合两个屏幕尺寸之一 720 x 480 或 1280 x 1024 图像尺寸来自 XML 文件 但这些尺寸是 Web 尺寸 我还从 XML 中选择了一些图像 这些图像的分辨率可能比 Web
  • 将名称字符串编码为唯一的数字

    我有一大堆名字 数以百万计 他们每个人都有一个名字 一个可选的中间名和一个姓氏 我需要将这些名称编码为唯一代表这些名称的数字 编码应该是一对一的 即一个名称只能与一个数字相关联 一个数字只能与一个名称相关联 对此进行编码的明智方法是什么 我

随机推荐

  • .NET 和 C++ 应用程序之间的 IPC

    是否有用于 NET 应用程序和本机 C 应用程序之间的进程间通信 IPC 的库 可以使用Socket进行简单的通信 它位于操作系统中 因此您不需要任何新的库 详细信息在C 套接字 and C 套接字 如果进程间通信始终在同一台计算机上完成
  • 自定义组件控件不断重新创建

    我是 Firemonkey 自定义控件的新手 很抱歉 如果这是一个平庸的问题或重复的问题 但我被困住了 无法弄清楚 这是我的自定义控件的代码 unit swScheduler interface uses System SysUtils S
  • 如何显示每天的事件?

    我有一个事件页面 我需要在其中显示每天的事件 我已经做到了这一点 所以我正在进步 数据库有3个表 fairdays eventtypes events fairdays id fairdaydate 日期时间 daycolor 描述 eve
  • UIAutomator 与 espresso 一起运行

    我目前正在测试一个应设置为默认启动器的应用程序 我已经有一套了Espresso测试正在运行 但仅当用户之前选择我的应用程序作为启动器时它们才有效 向用户显示的用于选择启动器的对话框无法通过Espresso 因为它位于应用程序本身之外 然而
  • 尝试对函数进行逆向工程

    我正在尝试更多地了解 x86 中的汇编 我这里有一个神秘的函数 我知道它返回一个int并采取int争论 所以看起来像int mystery int n 但是我无法弄清楚C 中的函数 大会是 mov edi eax lea 0x0 rdi 8
  • 从 java 调用 Google Cloud Run

    我想从外部应用程序调用 Cloud Run 外部应用程序是用 Kotlin java 编写的 并在 JDK 11 JVM 上运行 它使用服务帐户进行身份验证 ServiceAccountCredentials fromStream serv
  • 在模块 django.contrib.gis.db 中找不到 GeoManager。 Django 2.0 中的模型

    我正在开发 GeoDjango 项目 第一次在网络应用程序中工作 尝试使用 GeoManager 但弹出错误提示module django contrib gis db models has no attribute GeoManager
  • 如何在 PHP 中提取字符串的前 100 个字符

    我正在寻找一种方法 从字符串变量中提取前 100 个字符 放入另一个变量中进行打印 有没有一个函数可以轻松做到这一点 例如 string1 I am looking for a way to pull the first 100 chara
  • UITableView - 更改部分标题颜色

    如何更改 UITableView 中节标题的颜色 EDIT The DJ S提供的答案应考虑 iOS 6 及以上版本 接受的答案已过时 这是一个老问题 但我认为答案需要更新 此方法不涉及定义和创建您自己的自定义视图 在 iOS 6 及更高版
  • Codeigniter 选择具有多个 id 的数据

    这是我的代码的示例以及我想要做什么的解释 在代码的开头 我在数据库中选择三个变量 然后我将它们与确定距离的函数进行比较 如果距离在给定距离内 那么我就有了该记录的 ID 这将导致多个 id 可能是五个或没有 取决于给定的变量 我需要知道的是
  • 我如何在 php 中使用正则表达式匹配阿拉伯字母[重复]

    这个问题在这里已经有答案了 我如何在 php 中将阿拉伯字母与正则表达式匹配 My Code name GET name if arabic letters only and spaces using regexp 我想你的答案就在这里 根
  • 将字符串值发送到 Angular 2 中 url 导航上的组件

    当我使用 router navigate 方法时 我需要一些帮助来将字符串 bookingNumber 传递给组件 现在 我有一个名为 bookingsService 的服务 它有一个类似以下代码的方法 redirectToBookingP
  • 鸟瞰图或地图 2.5D 渲染存在问题

    我正在开发一个路线规划导航软件 我正在使用以下解决方案将我的道路线变成 2 5D 或 3D 视图 使用 C 从线条绘制 2 5D 或 3D 地图 然而 上面的解决方案对于视口内 0 height 或 x gt width 然后上述解决方案变
  • 为什么读会阻塞管道直到写端关闭?

    我正在努力增强我对相关事物的理解fork exec dup 并重定向stdin stdout stderr通过编写以下内容popen 类型函数 main c include
  • 通过 FileProvider 和 Intent 将缓存文件附加到 GMail 不起作用

    因此 在过去的一天里 我一直在用头撞墙 试图找出为什么文件无法附加到电子邮件中 每次应用程序运行时 我都会收到一条弹出的小消息 提示 无法附加文件 收件人和主题字段的填写正如我所期望的那样 第一个问题是 如何找到此错误背后的更多信息 此消息
  • DateTickUnit 文档在哪里?

    我需要更改 TimeseriesChart 不同缩放级别的默认 DateTickUnit 设置 但在文档中找不到我需要阅读的位置 我将非常感谢您的指点 以下是 TimeSeriesChartDemo1 的 Java API http www
  • Visual Studio 2015 IntelliSense 不显示所有方法

    我最近从 2013 升级到 Visual Studio 2015 因为出于某种原因 即使在多次安装尝试之后 2013 也无法在 Windows 10 上运行 The only issue is IntelliSense is not dis
  • 使用命令行上传到 iTunesConnect 时如何指定应用程序 ID

    Summary 我正在尝试将我的应用程序自动上传到 iTunes Connect 我至少有 6 个应用程序 并且全部都处于 准备上传 状态 问题是当我尝试使用命令行将应用程序上传到 iTunesConnect 时 出现以下错误消息 警告 i
  • Oracle聚合函数返回一组随机值?

    标准 SQL 聚合函数max 将返回一组中的最高值 min 将返回最低的 Oracle中是否有聚合函数可以从组中返回随机值 或者某种技术来实现这一目标 例如 给定表foo group id value 1 1 1 5 1 9 2 2 2 4
  • 返回 n 中 k 个元素的所有组合的算法

    我想编写一个函数 它接受一个字母数组作为参数 并选择其中的一些字母 假设您提供一个包含 8 个字母的数组 并希望从中选择 3 个字母 那么你应该得到 8 8 3 3 56 返回数组 或单词 每个数组由 3 个字母组成 计算机编程艺术第 4