python 递归实现二进制字符串(位串)相差固定汉明距离的所有位串

题目来自 程序设计导论(python 语言实践)的第二章,题目如下:

Hamming distance. The Hamming distance between two bit strings of length n is equal to the number of bits in which the two strings differ. Compose a program that takes an integer k and a bit string s from the command line, and writes all bit strings that have Hamming distance at most k from s

汉明距离,两个长度为 n 的二进制字符串(简称位串)的汉明距离定义为两个位串自检不同位的个数,编写一个程序,实现如下功能:带两个参数:汉明距离 k (整数) ,二进制字符串 s,输出与 s 的汉明距离为 k 的所有位串。

想了很久,都没有想出如何通过递归实现。在 stackoverflow.com 上的大神给出了代码,一开始还没看懂(有点小尴尬)

原文链接地址:点击打开链接

现将代码贴出,并进行简单的注释和扩展

# 反转字符,0 变 1,1 变 0
def flip(c):
    return str(1-int(c))


# 将字符串 s 中位置 i 的字符进行反转
def flip_s(s, i):
    t = s[:i] + flip(s[i]) + s[i+1:]
    return t


# 递归实现
def hamming(s, k):
    if k > 1:
        c = s[-1]
        # # s1 = [y+c for y in hamming(s[:-1], k)] if len(s) > k else []
        s1 = []
        if len(s) > k:
            for y in hamming(s[:-1], k):
                s1 += [y + c]
        else:
            s1 = []

        # s2 = [y+flip(c) for y in hamming(s[:-1], k-1)]
        s2 = []
        for y in hamming(s[:-1], k-1):
            s2 += [y + flip(c)]

        r = []
        r.extend(s1)
        r.extend(s2)
        return r
    else:
        return [flip_s(s, i) for i in range(len(s))]

print(hamming("0000", 2))

# >>> ['1100', '1010', '0110', '1001', '0110', '0011']

# 递归跟踪示意
'''
hanming('0000', 2):
    2 > 1    # (True, k == 2)
        c = '0'    # ('0000'[-1] == '0')
        4 > 2      # (True, len('0000') == 4)
            s1 = [y + '0' for y in hamming('000', 2)]
                hamming('000', 2)
                    2 > 1    # (True, k == 2)
                        c = '0'     # ('000'[-1] == '0')
                        3 > 2       # (True, len('000') == 3)
                            s1 = [y + '0' for y in hamming('00', 2)]
                                hamming('00', 2)
                                    2 > 1    # (True, k == 2)
                                        c = '0'    # ('00'[-1] == '0')
                                        2 > 2      # (False, len('00') == 2)
                                            s1 = []
                                        s2 = [y + flip('0') for y in hamming('0', 1)]
                                            hamming('0', 1)
                                                1 > 1    # (False, k == 1)
                                                    ['1']    # ([flip_s('0', i) for i in range(len('0'))])
                                                return ['1']
                                            s2 = ['11']
                                        r.extend(s1), r.extend(s1)
                                        # (r = ['11'])
                                        return ['11'] 
                                s1 = ['110']
                        s2 = [y + flip('0') for y in hamming('00', 1)]
                            hanming('00', 1)
                                1 > 1 (False, k == 1)
                                ['10', '01']    # ([flip_s('00', i) for i in range(len('00'))])
                                return ['10', '01']
                            s2 = ['101', '011']
                        r.extend(s1), r.extend(s1)
                        # (r = ['110', '101', '011'])
                        return ['110', '101', '011'] 
                s1 = ['1100', '1010', '0110']
        s2 = [y + flip('0') for y in hamming('000', 1)]
            hamming('000', 1)
                1 > 1 (False, k == 1)
                ['100', '010', '001']    # ([flip_s('00', i) for i in range(len('00'))])
                return ['100', '010', '001']
            s2 = ['1001', '0110', '0011']
        r.extend(s1), r.extend(s1)
        # r = ['1100', '1010', '0110', '1001', '0110', '0011']
        return ['1100', '1010', '0110', '1001', '0110', '0011']
'''

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值