递归函数

时间:2010-09-19 21:53:42

标签: php

我完全不知道,所以如果有人能指出我正确的方向,我们将不胜感激。

我想要像

这样的东西
<?php
function square($num) {
// something
}

name('{3}'); // have this return 9
name('{6}'); // have this return 36
name('{{{2}}}'); // have this return 256
name('{9}{12}'); // have this return 81144
name('{{5}}'); // have this return 125
name('adscdc{4}{{3}}'); // have this return adscdc1681
?>

有谁知道如何做到这一点?提前致谢 :) 到目前为止,我有:

<?php
function square($text) {
    $parts = explode('{', $text);
    foreach($parts as $part) {
        $piece = explode('}', $part);
        $text = str_replace('{' . $piece[0] . '}', pow($piece[0], 2), $text);
    }
    return $text;
}
echo square('aasd{3}');
?>

6 个答案:

答案 0 :(得分:3)

我认为{{5}}应该是625,对吗?

无论如何,尝试这样的事情:

<?php

  function name ($str) { 
    while (1) {
      preg_match('/{(\d+)}/', $str, $matches);
      if (count($matches)<2) return $str;
      $str=str_replace($matches[0], $matches[1]*$matches[1], $str);
    }
  }

  echo "\n<pre>\n".
       name('{3}'). // have this return 9
       "\n".
       name('{6}'). // have this return 36
       "\n".
       name('{{{2}}}'). // have this return 256
       "\n".
       name('{9}{12}'). // have this return 81144
       "\n".
       name('{{5}}'). // have this return 625
       "\n".
       name('adscdc{4}{{3}}'). // have this return adscdc1681
       "\n</pre>\n";

?>

...跑步给了我这些结果:

9
36
256
81144
625
adscdc1681

答案 1 :(得分:2)

您可能需要解析字符串。继续阅读角色,直到你到达一个打开的支撑,然后在每个打开的支撑增加一个计数器。当你到达一个号码时,将它提升到柜台的力量。然后递减每个右括号,如果大括号不匹配则抛出异常。

答案 2 :(得分:1)

看起来很简单。当您检测到大括号内的数字之类的动机时,应该用数字的平方代替。如果没有替换,你完成了。如果你做了一些替换你再做一次(因为刚刚被替换的东西现在可能在大括号内)等等。

第一部分(替换)可以使用正则表达式完成,第二部分可以递归地或迭代地完成。

下面的代码片段应该可以帮助您了解详细信息(不是完整的答案,但不是很远)。 exercice的目标似乎是帮助您理解preg_replace()参数。

<?php
$count = 0;
echo preg_replace('/[{](\d+)[}]/e', '$1*$1', '{{{2}}}', -1, $count);
echo "\n";
echo "$count replacement done\n";
?>

正如其他人提出的完整解决方案,这里是他的我的:

<?php

function square($str){
    $count = 0;
    do {
        $str = preg_replace('/[{](\d+)[}]/e', '$1*$1', $str, -1, $count);
    } while ($count);
    return $str;
}

echo square('{3}')."\n"; // have this return 9
echo square('{6}')."\n"; // have this return 36
echo square('{{{2}}}')."\n"; // have this return 256
echo square('{9}{12}')."\n"; // have this return 81144
echo square('{{5}}')."\n"; // have this return 125
echo square('adscdc{4}here')."\n"; // have this return adscdc1681

?>

如果您全神贯注于兼容性问题(因为强化的php安装可能禁止使用/ e),请使用preg_replace_callback代替preg_replace,如下所示(使用PHP 5.2.3中提供的匿名函数,对于较旧的php版本,您可以使用create_function())。

function square($str){
    $count = 0;
    do {
        $str = preg_replace_callback('/[{](\d+)[}]/',
                    function($m) {return $m[1]*$m[1];},
                    $str, -1, $count);
    } while ($count);
    return $str;
}

对于好奇的读者,正如其他人建议的python版本,下面是一个可能的perl等价物:

#!/usr/bin/perl

my @tests = ('{3}','{6}','{{{2}}}','{9}{12}','{{5}}', 'adscdc{4}{{3}}'); 

sub square {
    my $str = pop;
    while ($str =~ s/[{](\d+)[}]/$1*$1/e) {};
    return $str;
}

for my $str (@tests){
    print "$str --> ".square($str)."\n" ;
} 

Perl中存在安全机制以避免注入,因为恶意用户输入不同于盲目拒绝所有的逃避。对于那些感兴趣的人,你可以看看{{3}}。

另外两个较短的python版本,递归:

import re
test = ['5','{3}','{6}','{{{2}}}','{9}{12}','adscdc{4}{{3}}']

def square(txt):
   txt2 = re.sub('{(\d+)}',lambda m: str(int(m.group(1)) ** 2) , txt)
   if txt2 == txt:
        return txt
   return square(txt2)

for x in test:
    print("%s --> %s" % (x, square(x)))

和非递归

import re
test = ['5','{3}','{6}','{{{2}}}','{9}{12}','adscdc{4}{{3}}']

def square(txt):
    oldtxt = None
    while oldtxt != txt:
        oldtxt = txt
        txt = re.sub('{(\d+)}',lambda m: str(int(m.group(1)) ** 2) , oldtxt)
    return txt

for x in test:
    print("%s --> %s" % (x, square(x)))

答案 3 :(得分:1)

我认为这个问题很有意思。但是我已经在PHP中看到了一些很好的答案,所以仅仅为了自己的训练,我在Python中实现了一个解决方案。如果您有兴趣,可以看看:

>>> import re
>>> test = [('5','5'),('{3}','9'),('{6}','36'),('{{{2}}}','256'),('{9}{12}','81144'),('adscdc{4}{{3}}','adscdc1681')]
>>> def eval(txt):
...   replace = lambda t: re.sub('{(\d+)}',lambda match: str(int(match.group(1)) * int(match.group(1))),t)
...   while(re.search('[{}]',txt) != None):
...     txt = replace(txt)
...   return txt
... 
>>> for t in test:
...   print (t[0],t[1],eval(t[0]) == t[1])
... 
('5', '5', True)
('{3}', '9', True)
('{6}', '36', True)
('{{{2}}}', '256', True)
('{9}{12}', '81144', True)
('adscdc{4}{{3}}', 'adscdc1681', True)

有趣的是,python虽然是许多解决方案的强大语言,但在处理正则表达式时通常会产生非常难看的代码。

(这篇文章不是作为已发布问题的答案,因为已经有足够好的答案了。我只是为感兴趣的人分享它。)

答案 4 :(得分:0)

这个获得{}括号和每个括号在她中获得十进制数并且支持嵌套数量,输出结合到字符串代替解析括号而没有任何分隔符。

答案 5 :(得分:0)

这不一定是递归函数。除了其他人提到的核心逻辑之外,您还需要确保输入字符串是否有效。例如:

name('{{9}{{{{{1}');
name('{abbc}');
name('{}');