【问题标题】:Optimise the filtering of a infinite string in Haskell优化 Haskell 中无限字符串的过滤
【发布时间】:2020-06-13 15:59:48
【问题描述】:

我正在解决 HackerRank 中的一个问题,其中我必须计算无限重复序列字符串的第一个 n 元素中的字母 'a' 的数量,例如 "abc" 中的 "abcabcabcabc..."

我已经使用列表推导实现了以下功能:

repeatedString s n = length $ [x | x <- take (fromInteger n) (cycle s), x == 'a']

其中s 是重复序列,n 是从无限字符串中提取的元素数。

但 HackerRank 抱怨某些测试没有在时限内执行。

问题是:

  • 这里的瓶颈是什么?
  • 如何确定它们是否适用于类似的场合?
  • 您能指出一种更有效的方法吗?

非常感谢您!

编辑:澄清函数参数。

【问题讨论】:

  • 我没有看到这个问题,但我猜它包含了一些非常大的n 值。我不认为您可以使这种“直接”方法更有效,但是您当然可以简单地使用除法来计算所需的s 的完整周期数,然后将其乘以@987654331 中'a' 的数量@,然后直接处理余数。
  • 只计算一个字符串中a的个数,然后查看该字符串在n中出现的次数。
  • 是的,我曾考虑过这种方法,但想知道我的第一次拍摄是否还有其他事情要做。谢谢!
  • @DavSanchez:但它在 O(n) 中运行。如果 n 很大,那么这将永远存在。没有太大的瓶颈,它只是一种“幼稚”的计算方式。

标签: algorithm performance haskell optimization big-o


【解决方案1】:

您确实不需要需要明确计算as 的数量。你可以做的是:

  1. 统计'a'c中的数量;
  2. 检查您使s完整循环次数(将n 除以s 的长度);
  3. 计算在s最后(未完成)循环中发出了多少个字符;
  4. 统计该部分中'a's 的数量。
  5. 将完整循环的'a's 的数量和不完整循环的'a's 的数量相加。

因此程序如下所示:

repeatedString :: String -> Int -> Int
repeatedString s n = (length (filter ('a' ==) s) * div n (length s)) + …

处理最后一个(不完整)循环的部分您仍需要填写。

即使n 很大,算法仍然会在O(|s|)中运行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-30
    • 1970-01-01
    相关资源
    最近更新 更多