PHP 内置函数复杂度(isAnagramOfPalindrome 函数)

Posted

技术标签:

【中文标题】PHP 内置函数复杂度(isAnagramOfPalindrome 函数)【英文标题】:PHP built in functions complexity (isAnagramOfPalindrome function) 【发布时间】:2015-11-13 00:34:06 【问题描述】:

过去 2 小时我一直在谷歌搜索,但我找不到 php 内置函数时间和空间复杂度的列表。我有isAnagramOfPalindrome 问题要解决,最大允许复杂度如下:

expected worst-case time complexity is O(N)

expected worst-case space complexity is O(1) (not counting the storage required for input arguments).

其中 N 是输入字符串的长度。这是我最简单的解决方案,但我不知道它是否在复杂性限制内。

class Solution  

    // Function to determine if the input string can make a palindrome by rearranging it
    static public function isAnagramOfPalindrome($S) 

        // here I am counting how many characters have odd number of occurrences
        $odds = count(array_filter(count_chars($S, 1), function($var) 
            return($var & 1);
        ));
        // If the string length is odd, then a palindrome would have 1 character with odd number occurrences
        // If the string length is even, all characters should have even number of occurrences
        return (int)($odds == (strlen($S) & 1));
    


echo Solution :: isAnagramOfPalindrome($_POST['input']);

有人知道在哪里可以找到此类信息吗?

编辑

我发现array_filter 的复杂度为 O(N),count 的复杂度为 O(1)。现在我需要在count_chars 上查找信息,但是完整的列表对于将来的问题会非常方便。

编辑 2

在总体上对空间和时间复杂度进行了一些研究后,我发现这段代码具有 O(N) 时间复杂度和 O(1) 空间复杂度,因为:

count_chars 将循环 N 次(输入字符串的全长,开始复杂度为 O(N) )。这是生成一个最大字段数有限的数组(准确地说是 26 个,不同字符的数量),然后在这个数组上应用一个过滤器,这意味着过滤器最多循环 26 次。当将输入长度推向无穷大时,这个循环是微不足道的,它被视为一个常数。 Count 也适用于这个生成的常量数组,此外,它并不重要,因为count 函数的复杂度是 O(1)。因此,算法的时间复杂度为O(N)。

空间复杂度也是如此。在计算空间复杂度时,我们不计算输入,只计算过程中生成的对象。这些对象是 26 元素数组和 count 变量,它们都被视为常量,因为它们的大小不能超过这一点,无论输入有多大。所以我们可以说该算法的空间复杂度为 O(1)。

无论如何,该列表仍然很有价值,因此我们不必查看 php 源代码。 :)

【问题讨论】:

可能你得看源代码自己搞清楚。这是一个声称为某些功能提供此信息的问题的答案:***.com/questions/2473989/… 我遇到了这个,很棒的信息,但仅限于 array_filtercountcount_chars 上没有任何内容。 从技术上讲,有超过 26 个不同的字符。除非保证您的问题只提供英文字母表中的字符,否则 count_chars() 的最坏情况空间复杂度将是 min(N, )。另外,不要忘记考虑大写/小写... 本题中有一个列表:***.com/questions/2473989/… @Skatch 我建议您使用有关复杂性的资源来回答您的问题。 【参考方案1】:

不包含此信息的一个可能原因是可能会在每个版本中发生变化,因为已针对一般情况进行了改进/优化。

PHP 是基于 C 构建的,其中一些函数只是 c 对应物的包装器,例如 hypot 谷歌搜索,查看 man hypot,在数学库的文档中 http://www.gnu.org/software/libc/manual/html_node/Exponents-and-Logarithms.html#Exponents-and-Logarithms

来源实际上没有提供更好的信息 https://github.com/lattera/glibc/blob/a2f34833b1042d5d8eeb263b4cf4caaea138c4ad/math/w_hypot.c(非官方,链接方便)

别说,这只是glibc,Windows会有不同的实现。所以每个操作系统甚至可能有一个不同的大 O 编译 PHP

另一个原因可能是因为这会让大多数开发人员感到困惑。 我认识的大多数开发人员只会选择具有“最佳”大 O 的函数

最大值并不总是意味着它更慢

http://www.sorting-algorithms.com/

对某些函数发生的事情有很好的视觉支持,即冒泡排序是一种“慢”排序,但对于几乎排序的数据来说,它是最快的排序之一。 快速排序是许多人会使用的,这对于几乎排序的数据实际上非常慢。 大 O 是最坏的情况 - PHP 可能会在一个版本之间做出决定,他们应该针对特定条件进行优化,这将改变函数的大 O,并且没有简单的方法来记录它。

这里有一个部分列表(我猜你已经看到了)

List of Big-O for PHP functions

其中列出了一些更常见的 PHP 函数。

对于这个特定的例子......

不使用内置函数也很容易解决。

示例代码

function isPalAnagram($string) 
  $string = str_replace(" ", "", $string);
  $len = strlen($string);
  $oddCount = $len & 1;
  $string = str_split($string);
  while ($len > 0 && $oddCount >= 0) 
    $current = reset($string);
    $replace_count = 0;
    foreach($string as $key => &$char) 
      if ($char === $current)
        unset($string[$key]);
        $len--;
        $replace_count++;
        continue;
      
    
    $oddCount -= ($replace_count & 1);
  

  return ($len - $oddCount) === 0;


利用奇数不能超过 1 个这一事实,您可以提前从数组中返回。

认为我的也是 O(N) 时间,因为据我所知,最坏的情况是 O(N)。

测试

$a = microtime(true);
for($i=1; $i<100000; $i++) 
  testMethod("the quick brown fox jumped over the lazy dog");
  testMethod("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
  testMethod("testest");

 printf("Took %s seconds, %s memory", microtime(true) - $a, memory_get_peak_usage(true));

使用非常旧的硬件运行测试 我的方式

Took 64.125452041626 seconds, 262144 memory

你的方式

Took 112.96145009995 seconds, 262144 memory

我很确定我的方式也不是最快的方式。

对于 PHP 以外的语言(例如 Java),我实际上看不到太多信息。

我知道这篇文章的很多内容都在猜测为什么它不存在,并且没有很多来自可靠来源的资料,我希望它可以部分解释为什么大 O 没有列在文档页面中

【讨论】:

事后思考。您可能应该将字符串小写,因为这两种方法目前处理大小写的方式不同 这种信息存在于python中,所以我认为它可能也存在于php中......无论如何,这很有价值,我的第一个解决方案是没有内置函数,这种方式看起来更好,但我从没想过它可以产生如此大的差异(几乎翻倍)。

以上是关于PHP 内置函数复杂度(isAnagramOfPalindrome 函数)的主要内容,如果未能解决你的问题,请参考以下文章

PHP 好用的内置函数

PHP内置函数大全

8. Smarty3:模版中的内置函数

php数组函数有哪些操作?php数组函数的应用

内置 PHP 函数的 Netbeans 代码高亮显示

PHP & MySQL数据库专题 第六课 MySQL 内置函数