11## 2.4.一个乱序字符串检查的例子
22
3- 显示不同量级的算法的一个很好的例子是字符串的乱序检查。一个字符串是另一个字符串的乱序。如果第二个字符串只是第一个的重新排列, 例如,'heart' 和 'earth' 就是乱序字符串。'python' 和 'typhon' 也是。为了简单起见,我们假设所讨论的两个字符串具有相等的长度,并且他们由 26 个小写字母集合组成。我们的目标是写一个布尔函数,它将两个字符串做参数并返回它们是不是回文 。
3+ 显示不同量级的算法的一个很好的例子是字符串的乱序检查。乱序字符串是指一个字符串只是另一个字符串的重新排列。 例如,'heart' 和 'earth' 就是乱序字符串。'python' 和 'typhon' 也是。为了简单起见,我们假设所讨论的两个字符串具有相等的长度,并且他们由 26 个小写字母集合组成。我们的目标是写一个布尔函数,它将两个字符串做参数并返回它们是不是乱序 。
44
55### 2.4.1.解法1:检查
6- 我们对乱序问题的第一个解法是检查第一个字符串是不是出现在第二个字符串中。如果可以检验到每一个字符,那两个字符串一定是回文 。可以通过用 None 替换字符来完成检查 。但是,由于 Python 字符串是不可变的,所以第一步是将第二个字符串转换为列表。第一个字符串中的每个字符可以通过检查在第二个列表中检查元素是否存在 ,如果存在,替换成 None。见 ActiveCode1
6+ 我们对乱序问题的第一个解法是检查第一个字符串是不是出现在第二个字符串中。如果可以检验到每一个字符,那这两个字符串一定是乱序 。可以通过用 None 替换字符来了解一个字符是否完成检查 。但是,由于 Python 字符串是不可变的,所以第一步是将第二个字符串转换为列表。检查第一个字符串中的每个字符是否存在于第二个列表中 ,如果存在,替换成 None。见 ActiveCode1
77
88````
99def anagramSolution1(s1,s2):
@@ -41,7 +41,7 @@ print(anagramSolution1('abcd','dcba'))
4141
4242### 2.4.2.解法2:排序和比较
4343
44- 另一个解决方案是利用这么一个事实, 即使 s1,s2 不同,它们只有由完全相同的字符组成,它们才是回文 。所以,如果我们按照字母顺序排列每个字符串,从 a 到 z,如果两个字符串相同,则这两个字符串为回文 。见 ActiveCode2。
44+ 另一个解决方案是利用这么一个事实: 即使 s1,s2 不同,它们都是由完全相同的字符组成的 。所以,我们按照字母顺序从 a 到 z 排列每个字符串 ,如果两个字符串相同,那这两个字符串就是乱序字符串 。见 ActiveCode2。
4545
4646````
4747def anagramSolution2(s1,s2):
@@ -66,17 +66,17 @@ print(anagramSolution2('abcde','edcba'))
6666````
6767* ActiveCode2*
6868
69- 首先你可能认为这个算法是 O(n),因为只有一个简单的迭代来比较排序后的 n 个字符。但是,调用 Python 排序不是没有成本。正如我们将在后面的章节中看到的,排序通常是 O(n^2 ) 或 O(nlogn)。所以排序操作比迭代花费更多。最后该算法跟排序过程有同样的量级。
69+ 首先你可能认为这个算法是 O(n),因为只有一个简单的迭代来比较排序后的 n 个字符。但是,调用 Python 排序不是没有成本。正如我们将在后面的章节中看到的,排序通常是 O(n^2) 或 O(nlogn)。所以排序操作比迭代花费更多。最后该算法跟排序过程有同样的量级。
7070
7171### 2.4.3.解法3: 穷举法
7272
73- 解决这类问题的强力方法是穷举所有可能性。对于回文检测 ,我们可以生成 s1 的所有乱序字符串列表,然后查看是不是有 s2。这种方法有一点困难。当 s1 生成所有可能的字符串时,第一个位置有 n 种可能,第二个位置有 n-1 种,第三个位置有 n-3 种,等等。总数为 n∗(n−1)∗(n−2)∗...∗3∗2∗1n∗(n−1)∗(n−2)∗...∗3∗2∗1, 即 n!。虽然一些字符串可能是重复的,程序也不可能提前知道这样,所以他仍然会生成 n! 个字符串。
73+ 解决这类问题的强力方法是穷举所有可能性。对于乱序检测 ,我们可以生成 s1 的所有乱序字符串列表,然后查看是不是有 s2。这种方法有一点困难。当 s1 生成所有可能的字符串时,第一个位置有 n 种可能,第二个位置有 n-1 种,第三个位置有 n-3 种,等等。总数为 n∗(n−1)∗(n−2)∗...∗3∗2∗1n∗(n−1)∗(n−2)∗...∗3∗2∗1, 即 n!。虽然一些字符串可能是重复的,程序也不可能提前知道这样,所以他仍然会生成 n! 个字符串。
7474
7575事实证明,n! 比 n^2 增长还快,事实上,如果 s1 有 20个字符长,则将有 20! = 2,432,902,008,176,640,000 个字符串产生。如果我们每秒处理一种可能字符串,那么需要 77,146,816,596 年才能过完整个列表。所以这不是很好的解决方案。
7676
7777### 2.4.4.解法4: 计数和比较
7878
79- 我们最终解决回文的方法是利用两个乱序字符串具有相同的 a, b, c 等等的事实 。我们首先计算的是每个字母出现的次数。由于有 26 个可能的字符,我们就用 一个长度为 26 的列表,每个可能的字符占一个位置。每次看到一个特定的字符,就增加该位置的计数器。最后如果两个列表的计数器一样,则字符串为乱序字符串。见 ActiveCode 3
79+ 我们最终的解决方法是利用两个乱序字符串具有相同数目的 a, b, c 等字符的事实 。我们首先计算的是每个字母出现的次数。由于有 26 个可能的字符,我们就用 一个长度为 26 的列表,每个可能的字符占一个位置。每次看到一个特定的字符,就增加该位置的计数器。最后如果两个列表的计数器一样,则字符串为乱序字符串。见 ActiveCode 3
8080
8181```` python
8282def anagramSolution4 (s1 ,s2 ):
0 commit comments