惯用的Scala迭代所有子字符串[关闭]
Posted
技术标签:
【中文标题】惯用的Scala迭代所有子字符串[关闭]【英文标题】:Idiomatic Scala to iterate over all substrings [closed] 【发布时间】:2013-01-29 12:26:18 【问题描述】:比这更不重要的事情:
def subs(s: String) = for start <- 0 to s.length; end <- i to s.length yield s.substring(start, end)
【问题讨论】:
鉴于此代码运行良好,您可能希望将其发布到 codereview 而不是 ***。 我总是对各种不同的 stackexchange 网站感到困惑 - 有程序员、codereview、***、codegolf 以及大约六家其他网站,根据我的经验,我在这里得到的响应比其他任何地方都好。 我可能是错的,这就是我的感觉。 Codereview 似乎有更长的 sn-ps 代码,但它肯定是为了查看您的代码是否是惯用的。但我同意 *** 似乎是一个包罗万象的东西。程序员似乎更关注编程的非实际编码部分,即在团队中工作,处理文档等。Codegolf 只是试图获得最少的代码量。再说一次,你在这里的时间比我看起来要长得多。 我不知道你为什么认为这是必要的。没有变异状态,您使用的是yield
(而不是非yield
for
体内的某种累加器变异。它似乎也比@Rogach 的建议更透明。
start 和 end 是你可以争论的变异状态。我同意我上面的 sn-p 比 @rogach 的更具可读性,而且我总是会使用我的 snipper 而不是他的,但是在语言中,让你做 2 个列表的交叉乘积的命令式解决方案较少(例如在 Haskell 中)。跨度>
【参考方案1】:
scala> "asdf".inits.flatMap(_.tails).toList
res2: List[String] = List(asdf, sdf, df, f, "", asd, sd, d, "", as, s, "", a, "", "")
如果要删除空字符串:
scala> "asdf".inits.flatMap(_.tails.toList.init).toList
res3: List[String] = List(asdf, sdf, df, f, asd, sd, d, as, s, a)
但请注意,正如@Randall Schulz 在 cmets 中指出的那样,这种咒语对读者来说并不那么明显。另一方面,您的原始版本一目了然。
【讨论】:
+1,虽然 IMO 没有重复的空字符串会更好。 @AlexDiCarlo - 它生成与问题中的 sn-p 相同的结果。我实际上想不出一个摆脱空字符串的好方法 - 我可以附加.filter(_.nonEmpty)
,但这不会那么干净。
你可以用flatten
代替"asdf".inits.flatMap(_.tails).toList
其实我建议"asdf".inits.flatMap(_.tails).withFilter(!_.isEmpty).toList
过滤空字符串
@Jessica - 是的,它是 O(n^3)。您可以通过避免复制字符串(使用 CharBuffer 之类的东西)来优化它,这将使复杂度达到 O(n^2) 并在此过程中节省大量内存。但是,根据您的具体用例,可能有一种方法可以通过改进算法来进一步提高时间和内存使用率。以上是关于惯用的Scala迭代所有子字符串[关闭]的主要内容,如果未能解决你的问题,请参考以下文章
scala 字符串函数_Scala字符串连接,子字符串,长度函数