如何解决在 0 和 1 的 python 列表中确定序列类型的最有效方法?
假设我们有随机大小的 python 列表,其中的值是 0 和 1 的随机序列。确定序列是否为以下类型之一(最多 3 个位置)并为“序列类型”返回以下字符串之一的好方法是什么?:
-
0 (只有 0) [0,0]
-
1(只有 1 个)[1,1]
-
01(从 0 开始,然后遇到 1 x 位数)[0,1]
-
10(10 的倒数)[1,0]
-
010(从 0 开始,遇到 0 之后的 1 x 位数,然后是 1 之后的 0 x 位数)[0,1,0 ]
-
101(上面的倒数)[1,1]
我可以想到一些简单的情况,然后是一种天真的方法,您可以嵌套循环并保留一个计数器,但是有没有更优雅的方法来做到这一点?
def sequence_type(sequence):
if 0 not in sequence:
return '1'
elif 1 not in sequence:
return '0'
else:
if sequence[0] == 0:
# loop through for sequence type 0xx
elif sequence[0] == 1:
# loop through for sequence type 1xx
编辑:在检查类型时我们不关心序列末尾是什么,而是在查看前 3 个“唯一”数字时序列是什么。
例如:[0,0] 是类型 010 因为:
- 0 是第一个数字,它是我们的“起点”
- 然后我们向右走,看到它是另一个 0 所以它不是唯一的,跳过并再次向右移动
- 然后遇到一个 1,我们记录这个,因为它是唯一的,再次向右移动
- 看到数字是 0 并且是唯一的(我们现在数了 3 位),所以模式是 010。
解决方法
您可以通过逐位返回序列类型。类型的第一位数字始终等于第一位。如果在第一个位置之后找到逆位,则该类型将有两位或 3 位数字,第二位数字是第一位的倒数位。如果该位出现在逆位之后,则序列类型为 3 位(再次交替):
def seqType(seq):
bit = seq[0] # seq type starts with first bit
try: p = seq.index(1-bit) # search position of inverse bit
except: return str(bit) # not found --> single digit type
if bit not in seq[p+1:]: # search for initial bit after inverse
return f"{bit}{1-bit}" # not found --> two digit type
return f"{bit}{1-bit}{bit}" # --> 3 digit type
输出:
tests = ([0,0],[1,1],[0,1,1])
for seq in tests:
print(seq,seqType(seq))
[0,0] 0
[1,1] 1
[0,1] 01
[1,0] 10
[0,0] 010
[1,1] 101
如果您想要更高级的方法,可以使用 zip 函数计算类型以压缩相同的连续位。压缩序列的前 3 位将对应于序列类型:
def seqType(seq):
return "".join(str(a) for a,b in zip(seq,seq[1:]+[2]) if a!=b)[:3])
或者,如果您喜欢递归解决方案:
def seqType(seq):
if len(seq) == 1: return str(seq[0])
if seq[0]==seq[1]: return seqType(seq[1:])
return str(seq[0]) + seqType(seq[1:])[:2]
,
如果我对您的理解正确,您正在解析 regular language,因此您可以将其实现为 finite-state automaton。
这是一个 C 语言的例子:
bool start(char *s) {
if (*s) {
if (*s++ == '0') A(s);
else B(s);
} else /* empty string doesn't match anything (or it's both a type "0" and type "1" */
}
bool A(char *s) {
if (*s) {
if (*s++ == '0') A(s);
else C(s);
} else /* "0" */
}
bool B(char *s) {
if (*s) {
if (*s++ == '0') D(s);
else E(s)
} else /* "1" */
}
bool C(char *s) {
if (*s) {
if (*s++ == '0') /* "010" */
else /* Should be illegal. */
} else /* "01" */
}
bool D(char *s) {
if (*s) {
if (*s++ == '0') G(s);
else /* "101" */
} else /* "10" */
bool E(char *s) {
if (*s) {
if (*s++ == '0') F(s);
else E(s);
} else /* "1" */
}
bool F(char *s) {
if (*s) {
if (*s++ == '0') /* illegal */
else /* "101" */
} else
}
bool G(char *s) {
if (*s) {
if (*s++ == '0') G(s);
else /* "101" */
} else /* "10" */
}
这可能不是对有限状态自动机进行编码的最简洁的方式,但沿着这些思路应该可以工作——而且有限自动机当然是优雅的结构。
您也可以使用正则表达式。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。