迭代地查找字符数组中大小为 k 的所有组合(N 选择 K)

2023-12-26

我目前正在将这个问题作为个人项目来解决。

基本上:

  • 给定一个元素数组,例如E = {1,2,a,b} 且
  • 给定一个数字 K,例如K = 2
  • 我想全部退回组合 https://en.wikipedia.org/wiki/CombinationE 尺寸 K(E 选择 K)
  • 例如。 {{1,1}、{1,2}、{1,a}、{1,b}、{2,1}、...、{b,1}、{b,2}、{b, a}, {b,b}}

我已经使用以下函数递归地实现了这一点:

char[] pool = new char[]{'1', '2', '3'};

public void buildStringRec(char[] root, int pos, int length){
    for(char c : pool){
        char[] newRoot = root.clone();
        newRoot[pos] = c;
        if(pos+1 < length){
            buildStringRec(newRoot, pos+1, length);
        } else{
            System.out.println(String.valueOf(root));
        }
    }
}

Where pool是 E 且length is K.

所以我们会调用:buildStringRec(new char[2], 0, 2); and get

11
12
13
21
22
23
31
32
33

这可以迭代完成吗?我一直在尝试思考如何使用可变长度来做到这一点。

任何帮助,将不胜感激!如果需要的话,我可以按原样发布我的代码,但由于我的重试,它的变化非常频繁,以至于我一发布它就几乎毫无用处。

另外,我不想使用 Apache 或 String Builder 来执行此操作,因为我想了解如何执行此操作的概念。我不只是索要代码。伪代码只要解释清楚就可以了。

Thanks!

EDIT

我正在使用这个网站来测试向我提供的所有选项:https://ideone.com/k1WIa6 https://ideone.com/k1WIa6
请随意分叉并尝试一下!


递归解法

对我来说,递归解决方案似乎是最好的选择。
您可以用堆栈替换克隆路径数组以提高性能:

char[] pool = new char[]{'1', '2', '3'};
Stack<int> stack = new Stack<int>();

// Actually, resulting length should be the same length as pool array
int length = pool.length;

public void buildStringRec(int pos)
{
    if (length == pos + 1) 
    {
        System.out.println(String.valueOf(root));
        return;
    }

    for(char c : pool){
        stack.Push(c);
        buildStringRec(pos + 1);
        stack.Pop(c);
    }
}

迭代解决方案

假设由于某种原因,您需要迭代地执行此操作。
我确信有更好的解决方案。不过,这已经是我能做到的最好的了。

您可以将您的任务改写为另一项:

如何输出长度为 N 的以 N 为底的所有数字。

假设您有一个长度为 3 的数组:{'a', 1, 'z'}.
您理想的答案将是:

a-a-a    a-a-1    a-a-z
a-1-a    a-1-1    a-1-z
a-z-a    a-z-1    a-z-z
1-a-a    1-a-1    1-a-z

现在,让我们看看这些值的索引:

0-0-0    0-0-1    0-0-2
0-1-0    0-1-1    0-1-2
0-2-0    0-2-1    0-2-2 
2-0-0    2-0-1    2-0-2

实际上,这是一个以 3 为基数的连续数字:000, 001, 002, 010, 011, 012, 020, 021, 022, 200, 201, 202.

记住它们的计数公式:base ^ length。在我们的例子中,length == base。因此,它是base ^ base.

现在,我们的任务变得更容易了:

int[] toBase(long bs, long value)
{ 
    int[] result = new int[bs];
    for (long i = bs - 1; i >= 0; i--)
    {
        result[i] = (int)(value % bs);
        value = value / bs;
    }
    return result;
}

long Pow(long a, long b)
{
    long result = 1;
    for (int i = 0; i < b; i++) result *= a;
    return result;
}

char[] pool = new char[] {'a', 'b', 'c'};

void outputAll()
{
    long n = pool.Length;
    for (long i = 0; i < Pow(n, n); i++)
    {
        int[] indices = toBase(n, i);
        for (int j = 0; j < n; j++)
            Console.Write("{0} ", pool[indices[j]]);
        Console.WriteLine();
    }
}

当然,还可以进行一些优化:

  • 无需计算toBase每次。从 000 开始并每次计算下一个数字更容易且性能更高。
  • 你可以改变Pow快速使用的功能exponentiation by squaring算法等

这只是为了解释一种方法而提供的示例。

请记住,长度为 3 的数组将只有 27 个这样的组合。然而,长度为 7 的数组将有 823543。它呈指数增长。

工作样本

这里有一个DotNetFiddle 工作演示 https://dotnetfiddle.net/7lyEaB.

只是改变pool数组值以获得结果。 在这里和上面的所有示例中我都使用了 C#。它可以轻松转换为 C++ :)

对于我来说,它的长度在 7 以内(大约 1 - 1.5 秒)效果很好。
当然,您需要删除控制台输出才能获得这样的结果。控制台输出有效真的很慢.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

迭代地查找字符数组中大小为 k 的所有组合(N 选择 K) 的相关文章

  • 快速查找具有最大总不同元素的列表列表的子集

    给定元组列表的列表 我想找到列表的子集 该子集最大化不同整数值的数量 而不重复任何整数 该列表看起来像这样 x 1 2 3 8 9 10 15 16 2 3 10 11 9 10 11 17 18 19 20 21 22 4 5 11 12
  • 如何测试哈希函数?

    有没有办法测试哈希函数的质量 我希望在哈希表中使用时具有良好的分布 如果这可以在单元测试中验证 那就太好了 EDIT 为了澄清 我的问题是我已经使用了longJava 中的值的方式是第一个 32 位编码一个 ID 第二个 32 位编码另一个
  • 我可以在线性时间内检查有界列表是否包含重复项吗?

    假设我有一个Int列表 其中元素已知是有界的 并且列表已知不长于它们的范围 因此它完全有可能不包含重复项 如何才能最快地测试是否是这种情况 我知道nubOrd https hackage haskell org package contai
  • 在 Perl 中确定范围重叠的最快方法

    我有两组范围 每个范围都是一对整数 开始和结束 表示单个较大范围的某些子范围 两组范围的结构与此类似 当然 将替换为实际数字 a ranges a 1 gt start gt end gt a 2 gt start gt end gt a
  • 使用按键重新排列字符串

    我想使用Pythonrandomly根据给定的键重新排列字符串的各个部分 我还想用相同的密钥恢复原始字符串 def rearrange key data pass def restore key rearranged data pass 效
  • 给定一个数字 0-9 的数组和一个整数 n,找到可由输入数组组成且小于 n 的所有整数

    问题是这样的 给你一个数字 0 9 的数组和一个整数n 该数组可能包含任何给定数字的重复项 找到所有可以通过连接输入数组中的数字形成的整数并且小于n 输入数组中的数字可以在输出的元素中重复 例如 输入为 2 5 8 且 n 223 则输出应
  • 是否有任何算法可以计算给定定义形状的坐标的形状面积?

    所以我有一些接收 N 个随机数的函数2D点 是否有任何算法可以计算输入点定义的形状面积 你想要计算多边形的面积 http local wasp uwa edu au pbourke geometry polyarea 取自链接 转换为 C
  • 如何随机打乱地图中的值?

    我有一个 std map 其中键和值均为整数 现在我想随机打乱地图 因此键随机指向不同的值 我尝试了 random shuffle 但它无法编译 请注意 我并没有尝试洗牌键 这对于地图来说没有意义 我正在尝试随机化这些值 我可以将这些值推入
  • 求从1到N的所有数字的数字之和[重复]

    这个问题在这里已经有答案了 问题 求1到N 包括两端 所有数字的数字之和 时间复杂度应该是 O logN 对于 N 10 总和为 1 2 3 4 5 6 7 8 9 1 0 46 对于 N 11 总和为 1 2 3 4 5 6 7 8 9
  • 时间复杂度:连续对一个数字的数字进行求和,直到结果为一位数

    给我一个数字 N 不断对数字求和 直到结果为一位数 例如 35252 gt 17 gt 8 我写了以下代码 int digitSum int n int sum 0 int digit while n digit n 10 n n 10 s
  • 用二进制数、常规数字和格雷编码填充矩阵

    我有一个包含 1 s 或 0 s 的矩阵 用于创建二进制数 其宽度为n 对于 n 2 和 n 3 它看起来像 00 000 01 001 10 010 11 011 100 101 110 111 等等 现在我正在使用以下代码来生成它 in
  • 如何计算某物是否位于某人的视野中

    我有一个对象 它在 2D 空间中具有位置和速度 两者都由向量表示 对象的视野每侧均为 135 度 它看起来与移动的方向相同 速度矢量 我有一些对象 其在 2D 空间中的位置由向量表示 在图中 蓝色背景上的对象是可见的 红色背景上的对象对主体
  • 去除 OCR 图像处理中的背景颜色

    我正在尝试删除背景颜色 以提高 OCR 对图像的准确性 示例如下所示 我会将所有字母保留在后处理图像中 同时仅删除浅紫色纹理背景 是否可以使用一些开源软件如Imagemagick将其转换为二值图像 黑 白 来实现这一目标 如果背景有不止一种
  • MongoDB 全文搜索分数“分数是什么意思?”

    我正在为我的学校开发一个 MongoDB 项目 我有一个句子集合 我进行正常的文本搜索以查找集合中最相似的句子 这是基于评分的 我运行这个查询 db sentences find text search any text score met
  • 如何跟踪此对象图深度优先搜索算法中的深度?

    我有这段代码 它迭代一棵树 进行深度优先搜索 每个元素都只处理一次 非常好 void iterateOverTree TreeNode node NSMutableArray elements NSMutableArray array el
  • 原始数组的现代 for 循环

    原始数组上的 for 循环之间有性能差异吗 Assume double doubleArray new double 300000 for double var doubleArray someComplexCalculation var
  • 多个列表和大小的所有可能排列

    在 python 中使用以下命令很容易计算简单的排列itertools permutations https docs python org 3 library itertools html itertools permutations 你
  • 为什么循环引导迭代算法的数组大小必须为 3^k+1?

    The 循环引导迭代算法 http www geeksforgeeks org an in place algorithm for string transformation 是一种通过将所有偶数项移至前面并将所有奇数项移至后面同时保留其相
  • 在现实生活中,您会使用 heapq Python 模块做什么?

    读完吉多的书后使用 Python 对 2MB RAM 中的一百万个 32 位整数进行排序 http neopythonic blogspot com 2008 10 sorting million 32 bit integers in 2m
  • 在逻辑回归中使用排名数据

    当我努力学习这些概念时 我将对此给予最大赏金 我正在尝试在逻辑回归中使用一些排名数据 我想使用机器学习来制作一个简单的分类器来判断网页是否 好 这只是一个学习练习 所以我不期望有很好的结果 只是希望学习 过程 和编码技术 我已将数据放入 c

随机推荐