【问题标题】:Constructing Strings using Regular Expressions and Boolean logic ||使用正则表达式和布尔逻辑构造字符串 ||
【发布时间】:2011-09-27 11:38:43
【问题描述】:

如何从包含集合 {0,1} 中所有可能的元素组合的集合 E* 中构造恰好出现一次 111 的字符串?

【问题讨论】:

  • 这里:111。现在你完成了。或者你在问如何构造所有这样的字符串?还是别的什么?

标签: regex set regular-language


【解决方案1】:

您可以根据以下步骤生成字符串集:

列举了一些数字及其合法位置:


开始:110

必须有一个,任何地方:111

任何地方:0、010、0110

结束:011


取决于目标字符串的长度(长度应大于3)

条件 1:长度 = 3:{111}


条件 2: 6 > 长度 > 3 : (Length-3) = 1x + 3y + 4z


例如,如果长度为 5:答案为 (2,1,0) 和 (1,0,1)

(2,1,0) -> 两个'0'和一个'010' -> ^0^010^ or ^010^0^ (111可以放在任何一个标记为^的地方)

(1,0,1) -> 一个 '0' 和一个 '0110' ...

条件3:如果9 > Length > 6,你应该考虑两个公式的解:


评论:

length - 3 : 长度不包括 111

x: 0 发生的次数

y: 010 发生的次数

z: 0110 发生的次数


找到所有解决方案 {(x,y,z) | 1x + 3y + 4z = (长度 - 3)} ----(1)

对于每个解决方案,您可以生成一个或多个限定字符串。例如,如果要生成长度为 10 的字符串。 (x,y,z) 的一种解决方案是 (0,2,1),这意味着“010”应该出现两次,“0110”应该出现一次。基于此方案,可以生成如下字符串:


0: x0 次

010: x 2 次​​p>

0110:x1 次

111:x1 次(必须有)


找到上面元素的排列。 010-0110-010-111 或 111-010-010-0110 …

(长度 - 6) = 1x + 3y + 4z ---(2) 与上述情况类似,找到所有排列以形成中间字符串。 最后,对于每个中间字符串 Istr,Istr + 011 或 110 + Istr 都是合格的。

例如,(10-6) = 1*0 + 3*0 + 4*1 或 = 1*1 + 3*1 + 4*0

中间字符串可以由一个'0110'组成答案(0,0,1): 那么^0110^011和110^0110^就是合格的字符串(111可以放在任何一个标有^的地方)

或者中间字符串也可以由一个'0'和一个'010'组成答案(1,1,0)

中间字符串可以是 0 010 或 010 0 那么 ^0010^011 和 110^0100^ 是合格的字符串(111可以放在任何一个标记为^的地方)

条件4:如果Length > 9,需要考虑加法:


(长度 - 9)= 1x + 3y + 4z

与上述情况类似,找到所有排列以形成中间字符串。 最后,对于每个中间字符串 Istr,110 + Istr + 011 是合格的。


说明:

我使用的逻辑基于组合数学。目标字符串被视为一个或多个子字符串的组合。为了满足约束(“111”在目标字符串中恰好出现一次),我们应该对子字符串设置标准。 '111' 绝对是一个子串,而且只能使用一次。其他子字符串应防止违反 '111'-one-time 约束,并且足够通用以生成所有可能的目标字符串。

除了 only-one-111 之外,其他子串的相邻 '1' 不应超过两个。 (因为如果其他子串有两个以上相邻的1,例如'111'、'1111'、'11111',则子串会包含不必要的'111')。除了 only-one-111 之外,其他子串的连续 '1' 不应超过两个。因为如果其他子串有两个以上连续的 1,例如 '111', '1111', '11111',则子串会包含不必要的 '111' 。但是,子字符串 '1' 和 '11' 不能确保 only-one-111 约束。例如,'1'+'11'、'11'+'11' 或 '1'+'1'+'1' 都包含不必要的 '111'。为了防止不必要的'111',我们应该添加'0'来停止更多相邻的'1'。这会产生三个合格的子字符串“0”、“010”和“0110”。由三个合格子字符串组成的任何组合字符串都将包含零次“111”。

以上三个合格的子字符串可以放在目标字符串中的任何位置,因为它们 100% 确保目标字符串中没有额外的 '111'。

如果子字符串的位置在开头或结尾,它们只能使用一个'0'来防止'111'。

开始:

10xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

110xxxxxxxxxxxxxxxxxxxxxxxxxxx

最后:

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx011

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx01

这两种情况也可以确保没有额外的'111'。

基于上述逻辑。我们可以生成任意长度的目标字符串,其中恰好有一个 '111'。

【讨论】:

  • 我真的不明白你上面的答案。这个答案不应该取决于目标字符串的长度,因为它可以根据需要而定。我只需要确保 111 在字符串中只出现一次,不管它有多长。
  • 目标字符串的长度不受限制。此答案可用于生成任意长度的字符串。答案将所有问题空间划分为四个条件(l=3, 6>l>3, 9>l>6, l>9),并用略有不同的解决方案征服每个条件。
  • 求解公式可以使用约束编程的API(en.wikipedia.org/wiki/Constraint_programming),如python-constraint(labix.org/python-constraint)。
  • 为了解决这个问题,我真的更愿意在学习 Python 之前先了解其逻辑。我的意思是我认为我应该能够用任何语言为此编写一个生成器,只要我了解问题和解决方案。
  • @Kobojunkie 我在原始答案的底部添加了一些解释。希望对理解逻辑有所帮助。
【解决方案2】:

你的问题可能更清楚。

一方面,"1111" 是否包含一次或两次 "111"

如果是这样,您需要所有包含"111" 但不包含"1111""111.*111" 的字符串。如果不是,请省略"1111" 的测试。

如果我对您的理解正确,您正在尝试构建 0 和 1 的无限序列集的无限子集。您如何做到这一点可能取决于您使用的语言(大多数语言没有表示无限集的方法)。

我的最佳猜测是,您想生成一个包含所有 0 和 1 序列的序列(这应该不会太难)并选择符合您条件的序列。

【讨论】:

  • 我相信 1111 会算作 111 的两次出现。本质上,这种情况下的生成器应该将我的字符串中的子字符串 111 的出现限制为一个。
  • 我想编写代码来生成长度为 1 到 n 的字符串,但我只允许在每个字符串中出现一次子字符串“111”。只允许一个。不允许使用“1111011101111111”。只允许出现一次“111”。
猜你喜欢
  • 1970-01-01
  • 2016-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多