具有偶数个 a 和奇数个 b 的字符串的正则表达式

Posted

技术标签:

【中文标题】具有偶数个 a 和奇数个 b 的字符串的正则表达式【英文标题】:Regular expression for strings with even number of a's and odd no of b's 【发布时间】:2011-04-11 13:09:55 【问题描述】:

我在解决问题时遇到了问题:- 这是一个作业,我解决了,但它似乎太长和模糊,请任何人帮助我......

具有偶数个a和奇数个b的字符串的正则表达式,其中字符集=a,b。

【问题讨论】:

您应该发布您的解决方案,以便人们提出具体的改进建议。 正则表达式应该实现什么? 'a's 和 'b's 有多少个序列?你能展示你是如何解决它的吗?这可能有助于确定一个可以做同样事情的正则表达式。 你不想在这里使用 RegEx - 作业应该用一个简单的“不要!”来解决。和几行代码。 从我的回答中得到一个想法:How to write regular expression for a DFA using Arden theorem 【参考方案1】:

一种方法是通过 两个 正则表达式传递它,确保它们都匹配(假设您想使用正则表达式,请参阅下面的替代方法):

^b*(ab*ab*)*$
^a*ba*(ba*ba*)*$

其他任何事情(事实上,即使如此)很可能只是为了变得聪明,这通常是一个巨大的失败。

第一个正则表达式确保有偶数个 ab 在混合中的任何位置(之前、之后和中间)。

第二个类似,但确保有一个 奇数b 凭借起始 a*ba*


一个远更好的方法是完全忽略正则表达式并简单地遍历字符串,如下所示:

def isValid(s):
    set evenA to true
    set oddB to false
    for c as each character in s:
        if c is 'a':
            set evenA to not evenA
        else if c is 'b':
            set oddB to  not oddB
        else:
            return false
    return evenA and oddB

虽然正则表达式是一个很棒的工具,但它们并不适用于所有事情,而且随着可读性和可维护性的下降,它们的用处也大大降低。


对于它的价值,一个单一的正则表达式答案是:

(aa|bb|(ab|ba)(aa|bb)*(ba|ab))*(b|(ab|ba)(bb|aa)*a)

但是,如果我发现我的团队中的任何人实际上使用了这样的怪物,他们会被送回去再做一次。

这来自 Greg Bacon 的一篇论文。请参阅here 了解实际的内部工作原理。

【讨论】:

【参考方案2】:
    (bb)*a(aa)*ab(bb)* ab(bb)* a(aa)* b(aa)*(bb)* . . . . . .

可以有很多这样的正则表达式。您是否有任何其他条件,例如“以 a 开头”或类似的东西(除了奇数的“b”和偶数的“a”)?

【讨论】:

【参考方案3】:

答案是 (aa+ab+ba+bb)* b (aa+ab+ba+bb)*

【讨论】:

它可以接受具有奇数个a和偶数个b的baaab【参考方案4】:

(bb)* b (aa)* + (aa)* b (bb)*

这是处理所有带有奇数 b 甚至 a 的字符串的答案。

【讨论】:

【参考方案5】:

我会这样做:

正则表达式 even 匹配符号 a,然后是 b 的序列,然后是符号 a再次,然后是另一个 b 的序列,这样 b 的数量是偶数:

偶数 -> (a (bb)* a (bb )* | a b (bb)* a b ( bb)*)

正则表达式 oddb 的奇数总数执行相同操作:

奇数 -> (a b (bb)* a ( bb)* | a (bb)* a b ( bb)*)

由偶数个a和奇数个b组成的字符串:

以奇数个b开头,后面是偶数个oddeven个模式;李> 或以偶数个 b 开头,然后是 even 模式中的奇数个 odd 模式。

请注意,even 与字符串中 a/b 的奇偶性无关。

正则表达式 -> (

b (bb)* 偶数* (奇数 偶数* 奇数)* 偶数*

|

(bb)* 偶数* 奇数 偶数* (奇数 偶数* 奇数)* 偶数*

)

当然,可以替换最终正则表达式中出现的每一个 evenodd 以获得单个正则表达式。

很容易看出满足这个正则表达式的字符串确实会有偶数个a(因为符号a只出现在even 和 odd 子正则表达式,它们每个都使用两个 a)和奇数个 b(第一种情况: 1 b +偶数个b +偶数个odd;第二种情况:偶数个b 's + odd 的奇数)。

具有偶数个 a 和奇数个 b 的字符串将满足此正则表达式,因为它以零个或多个 b 开头的,然后是[一个a,零个或多个b,还有一个a和零个或多个b's],零次或多次。

【讨论】:

【参考方案6】:

一个高级建议:为该语言构造一个确定性有限自动机——非常简单,编码状态中as 和bs 的数量的奇偶校验,q0 甚至编码nr。 as 甚至 nr。 bs,并相应地转换---,然后将 DFA 转换为正则表达式(为此使用众所周知的算法或“从头开始”)。

这里的想法是利用 DFA(正则语言的算法描述)和正则表达式(正则语言的代数描述)之间众所周知的等价性。

【讨论】:

【参考方案7】:

如果是偶数个a后跟奇数个b (aa)*b(bb)* 应该可以工作

如果它是按任何顺序 (aa)*b(bb)* + b(bb)(aa) 应该可以工作

【讨论】:

【参考方案8】:

所有有偶数个a和奇数个b的字符串 (((aa+bb) * b(aa+bb) * ) + (A +((a+b)b(a+b)) *)) *

这里 A 代表空字符串。 A 可以忽略。

如果有任何错误请指出。

【讨论】:

这个问题已经很老了,已经有几个答案了。努力回答新问题。也看看How do I write a good answer【参考方案9】:

这个正则表达式接受所有偶数a和偶数b的字符串

r1=((ab+ba)(aa+bb)*(ab+ba)+(aa+bb))*

现在获取偶数 a 和奇数 b 的正则表达式

r2=(b+a(aa+bb)*(ab+ba))((ab+ba)(aa+bb)*(ab+ba)+(aa+bb))*

【讨论】:

【参考方案10】:

正则表达式如下:

    (aa|bb)*((ab|ba)(aa|bb)*(ab|ba)(aa|bb)*b)*

【讨论】:

【参考方案11】:
Even-Even = (aa+bb+(ab+ba)(aa+bb)*(ab+ba))*

(Even-Even 有偶数个 Aas 和 b 都有)

偶数 a 和奇数 b = Even-Even b Even-Even

这应该可行

【讨论】:

【参考方案12】:

对于偶数的 a 和 b,我们有正则表达式:

E =  (ab + ba) (aa+bb)* (ab+ba) *

对于偶数个a和奇数个b,我们只需在上面的表达式E中添加一个额外的b

所需的正则表达式将是:

E =  ((ab + ba) (aa+bb)* (ab+ba))* b ((ab + ba) (aa+bb)* (ab+ba))* 

【讨论】:

【参考方案13】:

执行此操作的结构化方法是制作一个转换图并从中构建正则表达式。 在这种情况下,正则表达式将是

(a((b(aa)*b)*a+b(aa)*ab)+b((a(bb)*a)*b+a(bb)*ba))b(a(bb)*a)*

它看起来很复杂,但它涵盖了所有可能出现的情况。

【讨论】:

以上是关于具有偶数个 a 和奇数个 b 的字符串的正则表达式的主要内容,如果未能解决你的问题,请参考以下文章

c++输入n及n个整数,按奇数升序,偶数降序排列输出

正则表达式 - 匹配包含“+”和“-”的字符串

如何用c语言编写可判断奇数偶数的小程序?

输入 10 个整数,将这 10 个数按升序排列,并且奇数在前偶数在后?

有限自动机需要正则表达式:偶数个 1 和偶数个 0

JAVA从键盘中输入20个整数将奇数和偶数存入不同的两个数组中 计算这两个数组中所有数据之和