import{_ as i,c as a,a as n,o as t}from"./app-CyezZKiD.js";const e={};function l(p,s){return t(),a("div",null,[...s[0]||(s[0]=[n(`

一、子序列的本质

子序列是从原字符串中选择任意数量的字符(可以是 0 个、1 个、...、所有字符),且保持这些字符的原始顺序形成的字符串。

例如:原字符串 "abc" 的子序列包括 "a", "b", "c", "ab", "ac", "bc", "abc" 和空字符串 ""(共 23=82^3 = 8 种可能性)。

二、位掩码(Bitmask)的引入

假设字符串长度为 n,我们可以用一个 n 位的二进制数来表示是否选择某个字符:

例如,对于字符串 "abc"n=3):

二进制数十进制选择情况生成子序列
1015选择第 1 个字符 "a" 和第 3 个字符 "c""ac"
0102选择第 2 个字符 "b""b"

三、遍历所有可能的二进制数

所有可能的二进制数范围是 0(全 0)到 2n12^n - 1(全 1)。例如,n=3 时:

四、如何将二进制数转换为子序列?

1. 外层循环:遍历所有可能的二进制数

对于 n=3,遍历 1 (001) 到 7 (111)。

2. 内层循环:检查每一位是否为 1

五、代码示例

def get_all_subsequences(s):
    n = len(s)
    subsequences = []
    # 遍历 1 到 2^n - 1 (排除空字符串)
    for mask in range(1, 1 << n):
        subseq = []
        for i in range(n):
            # 检查 mask 的第 i 位是否为 1
            if mask & (1 << i):
                subseq.append(s[i])
        subsequences.append(''.join(subseq))
    return subsequences

# 测试
print(get_all_subsequences("abc"))
# 输出: ['a', 'b', 'ab', 'c', 'ac', 'bc', 'abc']

六、应用场景

在处理类似 X 质数 的问题时,我们需要检查一个数字的所有数字子序列。通过这种位运算的方式,可以非常高效地生成所有组合并进行判断。

def solve_x_prime(num):
    s = str(num)
    n = len(s)
    for mask in range(1, 1 << n):
        subseq_str = ""
        for i in range(n):
            if mask & (1 << i):
                subseq_str += s[i]
        
        # 将生成的子序列转换为整数并判断是否为质数
        p = int(subseq_str)
        if is_prime(p):
            return True
    return False
`,21)])])}const k=i(e,[["render",l]]),d=JSON.parse('{"path":"/archives/ea20bdda-0d49-4472-a647-2e305a930d11/","title":"通过位运算快速生成所有的子序列","lang":"zh-CN","frontmatter":{"title":"通过位运算快速生成所有的子序列","createTime":"2026/01/09 16:15:00","cover":"/images/elysia/10.jpg","coverStyle":{"layout":"right"},"permalink":"/archives/ea20bdda-0d49-4472-a647-2e305a930d11/","description":"一、子序列的本质 子序列是从原字符串中选择任意数量的字符(可以是 0 个、1 个、...、所有字符),且保持这些字符的原始顺序形成的字符串。 例如:原字符串 \\"abc\\" 的子序列包括 \\"a\\", \\"b\\", \\"c\\", \\"ab\\", \\"ac\\", \\"bc\\", \\"abc\\" 和空字符串 \\"\\"(共 23=8 种可能性)。 二、位掩码(Bitmask)的引入 假设字符串...","head":[["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"通过位运算快速生成所有的子序列\\",\\"image\\":[\\"https://www.simengweb.com/images/elysia/10.jpg\\"],\\"dateModified\\":\\"2026-01-09T08:42:22.000Z\\",\\"author\\":[]}"],["meta",{"property":"og:url","content":"https://www.simengweb.com/archives/ea20bdda-0d49-4472-a647-2e305a930d11/"}],["meta",{"property":"og:site_name","content":"仲夏夜之梦"}],["meta",{"property":"og:title","content":"通过位运算快速生成所有的子序列"}],["meta",{"property":"og:description","content":"一、子序列的本质 子序列是从原字符串中选择任意数量的字符(可以是 0 个、1 个、...、所有字符),且保持这些字符的原始顺序形成的字符串。 例如:原字符串 \\"abc\\" 的子序列包括 \\"a\\", \\"b\\", \\"c\\", \\"ab\\", \\"ac\\", \\"bc\\", \\"abc\\" 和空字符串 \\"\\"(共 23=8 种可能性)。 二、位掩码(Bitmask)的引入 假设字符串..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:image","content":"https://www.simengweb.com/images/elysia/10.jpg"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2026-01-09T08:42:22.000Z"}],["meta",{"name":"twitter:card","content":"summary_large_image"}],["meta",{"name":"twitter:image:src","content":"https://www.simengweb.com/images/elysia/10.jpg"}],["meta",{"name":"twitter:image:alt","content":"通过位运算快速生成所有的子序列"}],["meta",{"property":"article:modified_time","content":"2026-01-09T08:42:22.000Z"}]]},"readingTime":{"minutes":2.22,"words":667},"git":{"createdTime":1767948142000,"updatedTime":1767948142000,"contributors":[{"name":"祀梦","username":"","email":"3501646051@qq.com","commits":1,"avatar":"https://gravatar.com/avatar/6406a81eeddc359cf3d3ce018797689fc6d014ff06215c27d0210b42e8f5a8ab?d=retro"}]},"autoDesc":true,"filePathRelative":"blog/technology/bitwise-subsequences.md","headers":[],"categoryList":[{"id":"126ac9","sort":10000,"name":"blog"},{"id":"750eb7","sort":10005,"name":"technology"}]}');export{k as comp,d as data};