正在寻找元组替换算法
Looking for a tuple substitution algorithm
我在一次面试中被问到这个问题。我知道这是一个组合问题,但我不知道如何递归求解。我主要是在寻找解决这类问题的方法。
给定例如
(a, b, c)
的元组输出:
(*, *, *), (*, *, c), (*, b, *), (*, b, c), (a, *, *), (a, *, c), (a, b, *), (a, b, c)
这是一个使用itertools.product
:的普通单行
list(itertools.product(*(('*', x) for x in seq)))
这给出了与请求相同的订单:
>>> list(itertools.product(*(('*', x) for x in "abc")))
[('*', '*', '*'), ('*', '*', 'c'), ('*', 'b', '*'), ('*', 'b', 'c'), ('a', '*', '*'), ('a', '*', 'c'), ('a', 'b', '*'), ('a', 'b', 'c')]
实现这个特定问题的一种简单方法:对于一个n元元组,只需从0循环到2^n-1,对于中间的每个整数,如果第k个二进制数字是1,那么元组中的第k个位置就是元组中的原始元素;如果该数字为0,则第k个位置为*。
当然,这种方法很容易溢出,而且不是递归的;然而,它可以简单地重写为递归程序(只需递归地探索每个二进制数字)。
类似于clwen的答案,但使用生成器函数,这非常适合组合问题:
def combinations(seq):
if len(seq) == 1:
yield ('*',)
yield (seq[0],)
else:
for first in combinations([seq[0]]):
for rest in combinations(seq[1:]):
yield first + rest
print list(combinations("abc"))
输出:
[('*', '*', '*'), ('*', '*', 'c'), ('*', 'b', '*'), ('*', 'b', 'c'),
('a', '*', '*'), ('a', '*', 'c'), ('a', 'b', '*'), ('a', 'b', 'c')]
假设顺序不相关,那么就开始吧。我使用了一个内部字符串使其更易于实现。该代码也适用于作为正整数的n
的任何n元组数组。
关于这个实现的一些解释:将基本情况设置为1-tuple(在我的实现中,长度为1的字符串)。在这种情况下,返回*
和参数的内容。否则,通过用*
或当前元素的内容替换当前元素,在递归中推进一个元素。
如果可以按照上述算法绘制决策树,则更容易理解。
def _combination(s):
if len(s) == 1:
return ['*', s]
else:
rest = _combination(s[1:])
output = []
for r in rest:
output.append('*' + r)
output.append(s[0] + r)
return output
def combination(t):
s = ''.join(c for c in t)
result = _combination(s)
output = []
for r in result:
output.append(format_tuple(r))
print ', '.join(output)
def format_tuple(s):
return '(' + ', '.join(s) + ')'
if __name__ == '__main__':
t = ('a', 'b', 'c')
combination(t)
程序输出:
(*, *, *), (a, *, *), (*, b, *), (a, b, *), (*, *, c), (a, *, c), (*, b, c), (a, b, c)
根据Kevin的评论更新。
根据涉及二进制计数的解决方案(比imho的组合方案好得多)
t_str = raw_input("Enter Tuple Values Separated By Spaces:")
t = t_str.split()
n = len(t)
bin_template = "{0:0"+str(n)+"b}"
for i in range(2**n):
bval = bin_template.format(i)
solution= "("+",".join(["*" if bval[i] == "0" else t[i] for i in range(n)])+")"
print solution
漂亮又短又快。。。并且它应该处理大小不超过32的元组(或者无论int有多大……甚至可能更大,因为python使用任意大的整数)
由于这是一个面试问题,面试官可能希望了解递归原理,因为这通常是这类组合问题的起点。
这个代码怎么样,以表明你理解:
def generate(x, state, level):
if level == len(x):
print state
else:
state[level] = '*'
generate(x, state, level+1)
state[level] = x[level]
generate(x, state, level+1)
if __name__ == '__main__':
x = [ 'a','b','c']
generate(x,['*','*','*'], 0)
相关文章:
- C++:TypeDef使用元组
- Pybind11:将元组列表从Python传递到C++
- 重载元组索引运算符-C++
- 在C++中,如何通过几种类型从元组中选择多个元素
- 将fold表达式与std::一起用于两个元组
- std::ranges::elements_view,用于自定义类似元组的数据
- 将元组的向量转换/构造为堆
- 专用于 std 元组的模板,而无需用户执行remove_cvref
- 将元组的向量构造成堆
- 元组由 Swig 生成的 Python 包装器返回,用于C++向量
- 将元组类型扩展为可变参数模板?
- 时间复杂度 当具有复合数据类型(如元组或对)时?
- 类内部和外部静态 constexpr 元组之间的差异
- 可变参数模板与使用元组在参数中添加不同的数据对
- 访问和打印元组中的数据,并使用 C++14 使用模板函数显示数据
- std::元组作为成员替换,方便宏
- 匹配部分专用化以按类型替换元组元素
- 为什么使用std ::元组和模板派生的类扣除/替换会扣除/替换
- 正在寻找元组替换算法
- 如何在编译时替换元组元素