给定序列中子序列的数量

31
如果我有一个序列 X = {x1,x2,....xm},那么我将拥有 (2^m) 个子序列。 能否有人解释一下如何直观地得出这个公式? 我可以从3个元素开始,然后是4个,最后是5个,推导到这个公式,但我不认为我理解了。这个“2”是从哪里来的?我没有进行任何除以二之类的操作。 谢谢您的帮助。

这是作业吗?听起来像是作业。 - GWW
10
@GWW:我从来没有遇到过这样的作业:"解释这个结果是如何直观地得出的"。当然,会有"证明它是正确的"。 - Steve Jessop
3
不,这是我算法课程的相关内容,我正在为一份作业学习。但这是书中提供的陈述。我正试图理解这个数学概念,以便能够自己解决新问题。感谢您的帮助。 - rgamber
@rgamber 有时候书籍会默认你已经了解一切... - KenIchi
13个回答

39

首先,你所谈论的是一个集合。其次,确实可以从一个集合中生成的不同子集数量等于2^m,其中m是该集合中元素的数量。我们可以通过以3个元素为例来得出这个结果:

S = {a, b, c}

现在,为了生成每个子集,我们可以使用二进制数字来表示元素的存在:

xxx where x is either 0 or 1

现在让我们枚举所有可能性:

000 // empty sub-set
001
010
011
100
101
110
111 // the original set it self!
让我们以011为例。第一个数字是0,那么a不在这个子集中,但是bc存在,因为它们各自的二进制位是1。现在,给定m(例如上面例子中的3)个二进制位,可以生成多少个二进制数(子集)?你应该现在就能回答这个问题 ;)

13
警告:在一个集合中,顺序并不重要。在一个序列中,顺序很重要,但它只有一种确定的顺序。因此,它们并不完全相同,但是子集/子序列的数量问题是相同的。这两个问题可以相互映射。 - John
是的。我是在序列的上下文中提出这个问题。谢谢@John! - rgamber

35

对于那些真正寻找子字符串的人(如标题或URL所示):

Subset: 2^n (Order doesn't matter in sets)
Subsequence: 2^n (Since we keep the original ordering, this is the same.)
Substring: n(n+1) * 1/2 (Elements must be consecutive)

3
虽然这可能是一个有价值的贡献,但它并没有回答原帖提出的问题,因此最好将其发布为评论而不是回答。 - Alexey Feldgendler

10
对于长度为 m 的序列中的每个元素,您都可以选择它或将其留下。因此,对于每个元素有2种处理方式。因此,处理所有 m 个元素的总方法数是 2 * 2 * 2 ...... m 次= 2 ^ m 次。

7
每次添加一个元素,可能性的数量就会增加一倍,这个2是从哪里来的呢?

6

变量 x_i 可能在子序列中,也可能不在。这就像一个比特位。在序列中,有 2^m 种组合来打开/关闭序列中的 m 个数字。


5

对于任何序列X = {x1,x2,....xm},都会有(2^m)个子序列,因为您可以“选择”长度为0、1、2、...、m的子序列,也就是说,在数学上,它是

"C(m,0) + C(m,1) + ... C(m,m)" ,这导致了2^m。

例如,假设字符串是“abc”,那么

C(3,0) = 1, ""

C(3,1) = 3, "a", "b", "c"

C(3,2) = 3, "ab", "bc", "ac"

C(3,3) = 1, "abc"

子序列的数量为8,即2^3。

有关更多详细信息,请访问http://en.wikipedia.org/wiki/Binomial_coefficient#Series_involving_binomial_coefficients


3
如果你有一个序列S,当你在S的末尾添加新元素x时会发生什么呢?
S的所有子序列仍然是你的新序列的子序列。所有那些在最后添加了x的子序列也是如此。
哇!每次添加一个元素,子序列数量就会翻倍。

1
为了扩展已接受的答案,可以用数学术语来思考子序列的数量。让我们以一个字符串为例:'ABC'。
字符串'ABC'的子序列数量:
=> C(3, 0) + C(3, 1) + C(3, 2) + C(3, 3) = 1 + 3 + 3 + 1 = 8 (2^3).

(注:C(m,n)代表长度为'm'的字符串中大小为'n'的子序列数量)
可以通过列举它们来轻松验证:
C(3, 0) = '', // Taking 0 letters at a time out of the given string.
C(3, 1) = 'A', 'B', 'C', // Taking 1 letter at a time.
C(3, 2) = 'AB', 'AC', 'BC', // Taking 2 letters at a time.
C(3, 3) = 'ABC'. // Taking 3 letters at a time.
(Total count = 8)

我们在子序列中保持字母的顺序不变,因此使用“组合”而不是“排列”。
注意:使用二项式定理求二项式系数之和=2^n。以下是证明:
From Binomial theorem,
(x + y)^n = C(n, 0) x^n y^0 + .... + C(n, n) x^0 y^n

Using x = 1, y = 1,
(1+1)^n = C(n, 0) 1^n 1^0 + .... + C(n, n) 1^0 1^n 
=> 2^n = C(n,0) + C(n,1) + .... + C(n,n)

那就是二项式定理,其中的“2”来自于二项式定理。

1
每次当你遇到一个字符时,你要么将它包含在你的子序列中,要么不将它包含在你的结果中。这意味着如果你将字符串视为树的根,则它将有两个子节点:一个是包括当前字符的子序列,另一个则不包括,这使它成为一棵二叉树。而平衡二叉树的节点数为n^m,其中n是分支因子,m是树的高度。我们知道分支因子是2,高度应该是字符串中字符的数量,因此它是2^M。

1
每个子序列的定义是通过选择或不选择 m 个元素中的每一个来实现的。由于有 m 个元素,每个元素都有两种可能的状态,所以您会得到 2^m 种可能性。

我认为你描述的不是序列,而是由不同公式定义的组合。 - Argote
一点也不。也许“possibilities”最好写成“可能的子序列”。 - anumi
我会在这件事上支持anumi。 - John

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接