zl程序教程

您现在的位置是:首页 >  前端

当前栏目

正则表达式解二元方程式代码

2023-06-13 09:14:36 时间

原文:http://blog.stevenlevithan.com/archives/algebra-with-regexes
我照着原文写出的正则还真的计算出了结果。上php例子:

复制代码代码如下:

<?php
/**
 *计算Ax+By=C
 */
functionsuan($A,$B,$C){
 $A--;
 $B--;
 $str=str_repeat("-",$C);
 $search="/^(.*)\1{".$A."}(.*)\2{".$B."}$/";
 preg_match($search,$str,$r);
 returnarray("x"=>strlen($r[1]),"y"=>strlen($r[2]));
}
$A=2;
$B=3;
$C=9;
$r=suan($A,$B,$C);
//测试
echo"计算".$A."x+".$B."y=".$C."<br/>";
echo"x=".($r[x])."<br/>";
echo"y=".($r[y]);
//输出
//计算2x+3y=9
//x=3
//y=1
?>

我解释下
来一个简单的式子来说:2x+3y=9

原理:
在此函数中生成出这样的正则
复制代码代码如下:
^(.*)\1{1}(.*)\2{2}$

去匹配一个长度为9的重复字符串“-”,匹配出两个分组的长度,就是他的x  和 y的值了

正则解释:
【(.*)】也就是0到无数个【.】点号。
\1就是引用一组。后面【{1}】就是重复1次。
后半是\2就是引用2组。后面【{2}】就是重复1次。
以下是那个英文博客的翻译:
二元方程17x+12y=51,其表达式【^(.*)\1{16}(.*)\2{11}$】。很好理解。【(.*)】也就是0到无数个【.】点号。(这里是接着上文说的,其实,【.】点号想表示的是字符“1”)
也就是0到无数个1,后面【\1】引用一次。后面【{16}】就是16次。作用于前面的【\1】,也就是16次引用。加上开始的【(.*)】一共正好17次。后面一个就不说了,跟这个一样。
正则引擎会依次尝试【(.*)】中0到无数个字符“1”,0个字符“1”,1个字符“1”,2个字符“1”一直增加的尝试。直到成功,否则要尝试完所有字符“1”的最大个数(这里是51个字符“1”)。

PS:没有考虑无解的情况,当无解时x和y都是0