正则练习:阶乘

发布于 2024-09-24 09:58:19 字数 278 浏览 6 评论 0原文

这是 StackOverlow 的一个实验性新功能:通过解决各种经典问题来锻炼你的正则表达式能力。没有唯一正确的答案,事实上我们应该收集尽可能多的正确答案,只要它们具有教育价值。接受所有口味,但请清楚记录。尽可能提供测试用例/片段来证明该模式“有效”。

我们如何使用正则表达式查找数字x是否是阶乘?

额外奖励:如果模式可以确定x = n!,它也可以找到n吗?

This is an experimental new feature for StackOverlow: exercising your regex muscles by solving various classical problems. There is no one right answer, and in fact we should collect as many right answers as possible, as long as they offer educational value. All flavors accepted, but please document it clearly. As much as practical, provide testcases/snippets to demonstrate that the pattern "works".

How can we find if a number x is a factorial using regex?

Bonus: if the pattern can determine that x = n!, can it also find n?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

苦行僧 2024-10-01 09:58:20

Java,具有无限长度的后向查找和嵌套引用(另请参阅 ideone.com):

import java.util.regex.*;

class Factorial {
static String assertPrefix(String pattern) {
   return "(?<=(?=^pattern).*)".replace("pattern", pattern);
}
public static void main(String[] args) {
   final Pattern FACTORIAL = Pattern.compile(
      "(?x) (?: inc stepUp)+"
         .replace("inc", "(?=(^|\\1 .))")
         //                      1

         .replace("stepUp", "(?: ^. | (?<=(^.*)) (?=(.*)) (?: notThereYet \\2)+ exactlyThere )")
         //                                2          3

         .replace("notThereYet", "(?:  (?=((?=\\3) .  |  \\4 .)) (?=\\1(.*)) (?=\\4\\5)  )")
         //                                           4                  5

         .replace("exactlyThere", "measure4 measure1")
            .replace("measure4", assertPrefix("\\4(.*)"))
            .replace("measure1", assertPrefix("\\1\\6"))
   );

   for (int n = 0; n < 1000; n++) {
      Matcher m = FACTORIAL.matcher(new String(new char[n]));
      if (m.matches()) {
         System.out.printf("%3s = %s!%n", n, m.group(1).length() + 1);
      }
   }
}
}

Java, with infinite length lookbehind and nested references (see also on ideone.com):

import java.util.regex.*;

class Factorial {
static String assertPrefix(String pattern) {
   return "(?<=(?=^pattern).*)".replace("pattern", pattern);
}
public static void main(String[] args) {
   final Pattern FACTORIAL = Pattern.compile(
      "(?x) (?: inc stepUp)+"
         .replace("inc", "(?=(^|\\1 .))")
         //                      1

         .replace("stepUp", "(?: ^. | (?<=(^.*)) (?=(.*)) (?: notThereYet \\2)+ exactlyThere )")
         //                                2          3

         .replace("notThereYet", "(?:  (?=((?=\\3) .  |  \\4 .)) (?=\\1(.*)) (?=\\4\\5)  )")
         //                                           4                  5

         .replace("exactlyThere", "measure4 measure1")
            .replace("measure4", assertPrefix("\\4(.*)"))
            .replace("measure1", assertPrefix("\\1\\6"))
   );

   for (int n = 0; n < 1000; n++) {
      Matcher m = FACTORIAL.matcher(new String(new char[n]));
      if (m.matches()) {
         System.out.printf("%3s = %s!%n", n, m.group(1).length() + 1);
      }
   }
}
}
拿命拼未来 2024-10-01 09:58:20

使用 C# 中的 .NET 平衡组(另请参阅 ideone.com):

var r = new Regex(@"(?xn) 

^(
   (
     ( ^.
     | (?=  (?<temp-n> .)+ )
       (?<= (?<fact>  .+)  )
       (?<n-temp> \k<fact> )+?
       (?(temp) (?!))
     )
     (?<n>)
   )+
 )$

");

for (int x = 0; x < 6000; x++) {
   Match m = r.Match("".PadLeft(x));
   if (m.Success) {
      Console.WriteLine("{0,4} = {1}! ", x, m.Groups["n"].Captures.Count);
   }
}

注意:

.NET 的版本ideone.com 使用的平衡组似乎有一个错误,导致上面的代码片段中不得不重复 +? 。在较新的版本中,简单的贪婪 + 可能就足够了。另请参阅:回溯平衡组贪婪重复可能会导致不平衡?

With .NET balancing groups, in C# (see also on ideone.com):

var r = new Regex(@"(?xn) 

^(
   (
     ( ^.
     | (?=  (?<temp-n> .)+ )
       (?<= (?<fact>  .+)  )
       (?<n-temp> \k<fact> )+?
       (?(temp) (?!))
     )
     (?<n>)
   )+
 )$

");

for (int x = 0; x < 6000; x++) {
   Match m = r.Match("".PadLeft(x));
   if (m.Success) {
      Console.WriteLine("{0,4} = {1}! ", x, m.Groups["n"].Captures.Count);
   }
}

Note:

The version of .NET used by ideone.com seems to have a bug in the balancing groups that made the reluctant repetition +? necessary in the above snippet. In newer versions, a simple greedy + may suffice. See also: Backtracking a balancing group in a greedy repetition may cause imbalance?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文