生成任意长度的任意字母的所有组合
假设我有一个任意大小的数组,其中包含单个字符。我想计算这些字符的所有可能组合,直到任意长度。
假设我的数组是 [1, 2, 3]。用户指定的长度为2。则可能的组合为[11, 22, 33, 12, 13, 23, 21, 31, 32]。
我很难找到一个合适的算法,该算法允许任意长度,而不仅仅是排列数组。哦,虽然速度并不是绝对关键,但它也应该相当快。
Say I have an array of arbitrary size holding single characters. I want to compute all possible combinations of those characters up to an arbitrary length.
So lets say my array is [1, 2, 3]. The user-specified length is 2. Then the possible combinations are [11, 22, 33, 12, 13, 23, 21, 31, 32].
I'm having real trouble finding a suitable algorithm that allows arbitrary lengths and not just permutates the array. Oh and while speed is not absolutely critical, it should be reasonably fast too.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
只需进行加进位即可。
假设你的数组包含 4 个符号,并且你想要长度为 3 的符号。
从 000 开始(即单词上的每个符号 = 字母表[0])
然后加起来:
000
001
002
003
010
011
...
该算法(给定这些索引)只是增加最低的数字。如果它达到了字母表中的符号数量,请增加先前的数字(遵循相同的规则)并将当前数字设置为 0。
C++ 代码:
代码未经测试,但应该可以解决问题。
Just do an add with carry.
Say your array contained 4 symbols and you want ones of length 3.
Start with 000 (i.e. each symbol on your word = alphabet[0])
Then add up:
000
001
002
003
010
011
...
The algorithm (given these indices) is just to increase the lowest number. If it reaches the number of symbols in your alphabet, increase the previous number (following the same rule) and set the current to 0.
C++ code:
Code is untested, but should do the trick.
Knuth 在计算机编程的艺术卷中深入介绍了组合和排列1. 这是我几年前编写的他的算法之一的实现(不要讨厌它的风格,它古老的代码):
这个程序的输出是:
如果你希望你的组合包含重复的元素,如 [11] [ 22] 和 [33],您可以使用上面的算法生成组合列表,然后通过执行以下操作将新元素附加到生成的列表:
...程序输出现在变为:
Knuth covers combinations and permutations in some depth in The Art of Computer Programming, vol 1. Here is an implementation of one of his algorithms I wrote some years ago (don't hate on the style, its ancient code):
Output of this program is:
If you want your combinations to include repeated elements like [11] [22] and [33], you can generate your list of combinations using the algorithm above, and then append to the generated list new elements, by doing something like this:
...and the program output now becomes:
一种方法是使用一个简单的计数器,您在内部将其解释为基数 N,其中 N 是数组中的项目数。然后,从 N 基数计数器中提取每个数字,并将其用作数组的索引。因此,如果您的数组是 [1,2] 并且用户指定的长度是 2,那么
这里的技巧就是您的基数 10 到基数 N 的转换代码,这并不是非常困难。
One way to do it would be with a simple counter that you internally interpret as base N, where N is the number of items in the array. You then extract each digit from the base N counter and use it as an index into your array. So if your array is [1,2] and the user specified length is 2, you have
The trick here will be your base-10 to base-N conversion code, which isn't terribly difficult.
如果您事先知道长度,那么您所需要的只是一些 for 循环。比如说,for length =
3
:现在概括一下,只需递归地执行,递归的每一步都使用一个 for 循环:
当然,如果您只是想要所有组合,您可以认为每个步骤作为基于
N
的数字,从1
到k^N - 1
,其中k
是长度。基本上你会得到,以
N
为基数(对于k
= 4):If you know the length before hand, all you need is some for loops. Say, for length =
3
:Now to generalize it, just do it recursively, each step of the recursion with one of the for loops:
Of course, if you simply want all combinations, you can just think of each step as an
N
-based number, from1
tok^N - 1
, wherek
is the length.Basically you would get, in base
N
(fork
= 4):使用彼得的算法效果很好;但是,如果您的字母集太大或字符串太长,则尝试将所有排列放入一个数组并返回该数组将不起作用。数组的大小将是字母表的大小加上字符串的长度。
我在 Perl 中创建了这个来解决这个问题:
像这样调用它:
my $c = Combiner->new(['a','b','c','d'],20) ;
。然后调用nextWord
来抓取下一个单词;如果nextWord
返回 0,则表示已完成。Using Peter's algorithm works great; however, if your letter set is too large or your string size too long, attempting to put all of the permutations in an array and returning the array won't work. The size of the array will be the size of the alphabet raised to the length of the string.
I created this in perl to take care of the problem:
Call it like this:
my $c = Combiner->new(['a','b','c','d'],20);
. Then callnextWord
to grab the next word; ifnextWord
returns 0, it means it's done.这是我在 Haskell 中的实现:
将此脚本加载到 GHCi 中。假设我们想要在字母表 {'a','b','c'} 中查找长度小于或等于 2 的所有字符串。以下 GHCi 会话可以做到这一点:
或者,如果您只想长度等于的字符串2:
小心
allwords ['a','b','c']
,因为它是一个无限列表!Here's my implementation in Haskell:
Load this script into GHCi. Suppose that we want to find all strings of length less than or equal to 2 over the alphabet {'a','b','c'}. The following GHCi session does that:
Or, if you want just the strings of length equal to 2:
Be careful with
allwords ['a','b','c']
for it is an infinite list!这是我写的。可能对你有帮助...
This is written by me. may be helpful for u...