【发布时间】:2012-09-07 06:26:57
【问题描述】:
对于长度为n的字符串,计算所有子字符串的公式为:n(n+1)/2 有人可以帮助我直观地理解这个公式吗?
维基百科说: “一个长度的字符串中符号只出现一次的子串的数量,是在符号之间选择两个不同位置开始/结束子串的方式的数量”
【问题讨论】:
标签: algorithm math combinations
对于长度为n的字符串,计算所有子字符串的公式为:n(n+1)/2 有人可以帮助我直观地理解这个公式吗?
维基百科说: “一个长度的字符串中符号只出现一次的子串的数量,是在符号之间选择两个不同位置开始/结束子串的方式的数量”
【问题讨论】:
标签: algorithm math combinations
要理解这一点,请注意任何子字符串都需要两个参数:开始索引和结束索引。
例如:string str = "Hello World"; // 长度 == 11
让我们从一次只取一个字符的子字符串开始:H, e, l, l, o, , W, o, r, l, d。然后每次取 2 个字符:He、el、ll、lo、o、W、Wo 或 rl、ld。然后取 3 个字符:Hel、.. 等。
所以总的子串数是 11 + 10 + 9 + .. + 1,一般来说,for i from 1 to n,我们有 n - i + 1 子串。通过峰会:
从 i = 1 到 n 的 Sigma (n + 1 - i),产生 n * (n + 1) - n * (n + 1) / 2,即 n * (n + 1) / 2
【讨论】:
子字符串由它在原始字符串中的开始位置和结束位置决定。 对于任何子串,我们都有这两个端点。相反,对于字符串中的任何两个字符,只有一个子字符串在这些点开始和结束。
因此,所有子字符串的数量是所有(不一定是不同的)字符对的数量。
有n*(n-1)/2 对不同的字符。您还需要添加非不同对,即 n。
所以总数是n * (n-1) / 2 + n = n * (n+1) / 2。
【讨论】:
嗯,它是长度为 1(正好是 n)的所有子串的总和, 加上所有长度为 2 (n-1) 的子串, 加上所有长度为 n 的子字符串(这是一个正确的字符串)。然后,你有 n + n-1 + n-2 ... + 1 = (n * (n+1)) / 2
总和可以使用自然归纳法计算,并且由于高斯在学校时解决了这个总和而为人所知。
【讨论】:
子字符串由它的两个端点定义,基本上我们可以将子字符串视为字符串的切片。 让我们通过一个例子来理解它。 考虑长度为 3 的字符串“abc”
a b c
要对字符串进行切片,我们有 4 个位置,从 a 之前到 c 之后的字符串结尾。从这 4 个可用选项中,我们必须选择 2 个位置来创建切片,即等于 4C2 == n+1C2==n*(n+1)/2
【讨论】:
我不擅长数学,但是字符串的substrings 是什么,以及获得字符串的substrings 的可能性有哪些,我会尝试向您解释。
举个例子:“MOBILE”这是一个6个字符的字符串,现在根据你的公式 n(n+1)/2 结果为 6(6+1)/2=21
所以子字符串是在整个字符串之间有开始索引和结束索引的任何字符串。
在字符串“MOBILE”下面是我们可以拥有的子字符串:
第 1 步:“M”开始索引“M”和结束索引“M”这是一种可能性
第 2 步:“MO”开始索引“M”和结束索引“O”这是第二种可能性
.
.
第 5 步:“MOBIL”开始索引“M”和结束索引“L”这是第五种可能性
.
.
第 8 步:“OB”开始索引“O”和结束索引“B”这是八种可能性
.
.
第 21 步:“MOBILE”开始索引“E”和结束索引“E”这是第 21 种可能性
这些是在字符串中包含子字符串并且子字符串结尾索引不能小于起始索引的可能性。
【讨论】:
假设你想找出“abc”的子串, 那将是 {"a","ab","abc","b","bc","c"} 我们将通过以下代码计算它
for(int i=0;i<len;i++){
for(int j=i;j<len;j++){
}
}
看这段代码,很容易看出循环是这样运行的
第一次运行 3 次, 第二轮2次,第三轮1次
由于它每次都返回一个子字符串,因此等于n的总和 即 = n(n + 1) / 2
【讨论】: