0
A
回答
2
這個簡單的線性時間算法取自"Algorithms for subsequence combinatorics" by Cees Elzinga et al. (2008),略有修改,因爲數學往往是1索引,但Python是0索引。它適用於任何序列s
工作,不只是二進制序列:
def count_unique_subsequences(s):
"""Returns the number of unique subsequences of the sequence s"""
L = {}
N = []
count = 1
for c in s:
N.append(count)
count *= 2
if c in L:
count -= N[L[c] - 1]
L[c] = len(N)
return count
這是一個動態編程解決方案,其迭代計算當前字符串的每個前綴的獨特子的數目。所有這些子序列仍然是下一個前綴的子序列,另外我們可以添加任何擴展下一個字符的子序列,除了那些最後一次遇到相同字符時沒有擴展的子序列。 (因爲在那一點上,我們計算了用字符擴展的所有子序列)。在該算法中,向量N
保持每個連續前綴s
的唯一子序列的計數(由前綴的長度索引),而L
保持跟蹤每個角色最後一次出現的指數。
想到這段代碼後,我意識到N
真的是多餘的;我們需要的唯一原因是能夠查找與當前字符對應的子序列計數。但是我們可以將該計數直接存儲到L
而不是存儲第二個表查找的索引。這不會改變算法的時間複雜度(儘管它稍微加快了速度),但它確實將空間複雜度降低到O(| Σ |),其中Σ是字母表。對於二進制序列,它使算法成爲線性時間/恆定空間。下面是修改後的算法:
def count_unique_subsequences(s):
"""Returns the number of unique subsequences of the sequence s"""
L = {}
count = 1
for c in s:
adds = count - L.get(c, 0)
L[c] = count
count += adds
return count
至於提出的函數計算其不會出現在你的枚舉空序列,所以你可能要減一的最終結果。
在許多其他有趣的結果中,Elzinga論文還考慮了給定大小的字母表的最大獨特子序列數,表明最大數是一個廣義Fibonacci序列。對於字母大小2,最大計數可以計算爲:
max_count(0) = 1
max_count(1) = 2
max_count(n) = max_count(n - 2) + max_count(n - 1) + 1
這就是fibonacci(n+2)-1
。
生成最大模式的字符串由字母表的循環重複組成。
實際上枚舉所有獨特的子序列因此必須採取指數時間,因爲有(可能)指數數量的這樣的序列。但是,指數(對於二進制序列)是φ,它小於2.
相關問題
- 1. 二進制序列子求和組合
- 2. 如何搜索二進制數據中的唯一序列?
- 3. DateTime數組的二進制序列化
- 4. 查找二進制二維數組中的唯一行
- 5. 二進制搜索按列排序的二維數組只搜索第一列
- 6. 唯一的二進制搜索樹
- 7. 二進制數組
- 8. 排序數組的二進制搜索
- 9. 更新gui二進制數組列表
- 10. 快速排序二進制數組
- 11. 從數據庫C反序列化二進制數組#
- 12. 劃分二進制序列
- 13. 如何將數組編碼爲二進制並將二進制數據解組到二進制數組中?
- 14. 按升序列印二進制數字
- 15. 二進制序列化/反序列化
- 16. 序列化 - 反序列化(二進制)
- 17. 如何按二進制表示法對二進制數組進行排序
- 18. Java中一個數字的所有二進制組合列表
- 19. 列表的二進制(反)序列化
- 20. 整數數組二進制數組
- 21. 二進制數組到base64
- 22. 按二進制數組選擇數組
- 23. 從python中的二進制序列創建一個二叉樹
- 24. 如何按第一個子數組值排序數組(二維數組)陣列
- 25. R:將多個二進制列轉換爲一個因子變量,其因子是二進制列名
- 26. 如何在降序排列的數組中進行二進制搜索?
- 27. 二進制序列化到列表
- 28. PHP - 二維數組中的所有排列 - 唯一和有序的值
- 29. 排序二進制序列有R
- 30. WCF中的二進制序列化NetTCPBinding
如何使用數學? – bezet
110爲什麼不算101? – Yunnosch
很奇怪的任務。什麼是真正的問題?什麼是最大長度? – MBo