【问题标题】:How to construct regular expression to balance characters in a string?如何构造正则表达式来平衡字符串中的字符?
【发布时间】:2017-06-12 09:10:43
【问题描述】:

我遇到过解决不同问题的正则表达式,但我找不到 regex 来平衡字符串中的字符。

我遇到了一个问题,要查找字符串是否平衡。 例如:aabbccdd 是平衡的,因为字符以偶数重复 但aabbccddd 不是一个平衡的,因为ddd 在奇数模式下重复。这适用于所有输入非特定a,b,c and d 的字符。如果我输入12344321123454321,它应该分别返回平衡和不平衡的结果。

如何使用正则表达式找到余额。我们应该使用什么类型的正则表达式来查找字符串是否平衡?

Edit:

我尝试仅使用正则表达式找到解决方案,因为问题需要以正则表达式模式回答。如果没有明确提及正则表达式,我将使用任何其他解决方案来实现

【问题讨论】:

  • 为什么需要正则表达式?
  • 我从不喜欢 Java,但是在阅读了所有答案和 cmets 之后——我知道——我永远不会切换到 Java。在 python 中,这个问题是大约 2-5 行没有正则表达式和特定库的代码......仍然无法相信你不能在 java 中计算字符串中的字符......实际上这里是这样的答案:stackoverflow.com/questions/275944/…,现在只有比较字符串中每个字符的计数......它实际上是预期的 1-liner
  • @Drako 请记住,OP 要求基于 RegExps 的解决方案(我实际上怀疑这是一个考试技巧问题)。关于 Java,它最近经历了一些发展,然后是 Groovy 和 Kotlin,它们通过添加 Python 自古以来提供的所有语法糖,肯定会抢占 Java 的风头。
  • @classstacker 你可能是对的,因为我来到这里是为了正则表达式标签,发现即使可以编写它也不需要正则表达式,在 python 中不使用 lambdas会进一步缩短它,工作示例有 3-4 行 :) 我相信只需几行就可以在 Java 中做同样的事情 :) 所以真的必须是正则表达式折磨的学校问题 :)
  • @classstacker 这是检查学生是否知道如何从 DFA 或 NFA 转换为正则表达式的完美任务。对我来说,如果提供转换算法,DFA 就足够了。

标签: java regex string balance


【解决方案1】:

我认为你不能用正则表达式来做到这一点。为什么需要使用它们? 我试过这个:它有效,而且非常简单

static boolean isBalanced(String str) {
    ArrayList<Character> odds = new ArrayList<>(); //Will contain the characters read until now an odd number of times
    for (char x : str.toCharArray()) { //Reads each char of the string
        if (odds.contains(x)) { //If x was in the arraylist we found x an even number of times so let's remove it
            odds.remove(odds.indexOf(x));
        }
        else {
            odds.add(x);
        }
    }
    return odds.isEmpty();
}

【讨论】:

  • 我用所有四个 OP 示例尝试了我的代码,它返回了正确的值。 12344321 返回真,123454321 返回假。
  • 抱歉,从我的其他 cmets 中可以看出,我认为“平衡”是通过连续重复相同的字符数次或具有对称字符串来定义的。
  • 我尝试使用正则表达式找到解决方案,因为问题需要以正则表达式模式回答。如果没有明确提到正则表达式,我会使用任何其他解决方案
【解决方案2】:

存在这个问题的正则表达式,但不会加速任何事情,而且会完全混乱。准备NFA更容易,然后切换到REGEX。不过,它不是合适的工具。

public static void main(String args[]) {
    String s = args[0];
    int[] counter = new int[256];
    for (int i = 0; i < s.length(); i++) {
        counter[s.charAt(i)]++;
    }
    if (validate(counter)) {
        System.out.println("valid");
    } else {
        System.out.println("invalid");
    }
}

public static boolean validate(int[] tab) {
    for (int i : tab) {
        if (i%2 == 1) {
            return false;
        }
    }
    return true;
}

编辑: 用于指向正则表达式的存在

仅针对两个字符的有限自动操作的参考。从最左边开始,以双圈获胜。每个状态都由迄今为止具有奇数的字符集命名。

【讨论】:

  • @classstacker L={0,1} 更容易理解。很好解释stackoverflow.com/a/19615508/4723795
  • @classstacker 正则表达式对于 NFA 来说是 izomorfic,并且 nfa 只会逐个字符地读取字符,并且对于每个字符,它将有 2 个状态 - 偶数和奇数。它只会切换。
  • @classstacker 请检查答案所附的 DFA。 cs.stackexchange.com/questions/2016/… 描述了转换
  • 对不起,正如您从我的其他 cmets 中看到的那样,我认为“平衡”是通过连续重复相同字符的时间或具有对称字符串来定义的。那需要数数。
  • @classstacker 显然这将需要与有限自动化冲突的 inf 个状态
猜你喜欢
  • 2019-01-17
  • 2019-02-09
  • 1970-01-01
  • 2022-01-16
  • 2021-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多