String 使用scala开始的后缀数组

String 使用scala开始的后缀数组,string,scala,suffix-array,String,Scala,Suffix Array,今天,我尝试使用scala创建后缀数组。我可以用大量的代码行来实现这一点,但后来我听说,通过压缩和排序,只需使用很少的代码行就可以创建它 我现在的问题是开头。我尝试使用二进制搜索和zipWithIndex创建以下“树”,但到目前为止,我还没有创建任何东西。我甚至不知道是否可以只使用一条线,但我打赌它是lol 我想做的是从“芝士蛋糕”这个词中得到如下信息: Seq((cheesecake, 0), (heesecake, 1), (eesecake, 2), (es

今天,我尝试使用scala创建后缀数组。我可以用大量的代码行来实现这一点,但后来我听说,通过压缩和排序,只需使用很少的代码行就可以创建它

我现在的问题是开头。我尝试使用二进制搜索和zipWithIndex创建以下“树”,但到目前为止,我还没有创建任何东西。我甚至不知道是否可以只使用一条线,但我打赌它是lol

我想做的是从“芝士蛋糕”这个词中得到如下信息:

 Seq((cheesecake, 0),
     (heesecake, 1),
     (eesecake, 2),
     (esecake, 3),
     (secake, 4),
     (ecake, 5),
     (cake, 6),
     (ake, 7),
     (ke, 8),
     (e, 9))
有人能把我推到正确的路径吗?

一种方法

"cheesecake".reverse.inits.map(_.reverse).zipWithIndex.toArray

Scala字符串配备了有序集合方法,如
reverse
inits
,后者提供了一个字符串集合,其中每个字符串都删除了最新的字符。

要生成
字符串
(或任何其他)的所有可能的后缀,您只需使用以下方法:

如果需要索引,则可以使用:


您正在寻找
.scan
方法,特别是
.scanRight
(因为您希望从字符串的末尾(即右侧)开始构建,所以要在下一个字符之前加上前缀(从金字塔底部到顶部查看))

引述:

生成一个集合,其中包含应用 接线员从右向左走

这里的操作员是:

  • 在当前字符前加前缀
  • 递减计数器(因为您的第一个元素是
    “cheesecake”.length
    ,倒计时)
因此:


最后的
dropRight(0)
是删除
(List[(String,Int)]())
(第一个参数),它是开始构建的第一个元素(您可以传递字符串的最后一个
e
,并在
cheesecak
上迭代,但我发现这样做更容易).

编辑-根据我之前提出的
后缀
问题(从练习中,我认为
后缀
也应该/可能包括空列表,即
用于字符串

scala> def suffix(x: String): List[String] = x.toList match {
     |    case Nil             => Nil
     |    case xxs @ (_ :: xs) => xxs.mkString :: suffix(xs.mkString)
     | }
suffix: (x: String)List[String]

scala> def f(x: String): List[(String, Int)] = suffix(x).zipWithIndex
f: (x: String)List[(String, Int)]
试验


非常感谢大家。我的代码现在看起来好多了:)直到下一次我被stuckYou可能会发现这个Haskell实现很有趣-嗯,是的,我确实看到了答案(并且对它进行了投票,因为它在这个问题上比我的要清楚得多)。但是看到问题中的“金字塔”让我想到了
.scan
,这是这类问题的一般解决方案(折叠和累积中间结果)(此处不需要)。很抱歉,我在错误答案下发布了这一点。那就是我偷了你推荐的dropRight,然后把它放在了kossi的下面,我想放在那里。干得好:>
scala> "cheesecake".tails.toList.zipWithIndex
res0: List[(String, Int)] = List((cheesecake,0), (heesecake,1), (eesecake,2), (esecake,3), (secake,4), (ecake,5), (cake,6), (ake,7), (ke,8), (e,9), ("",10))
scala> s.scanRight (List[(String, Int)]())
                   { case (char, (stringAcc, count)::tl) => (char + stringAcc, count-1)::tl
                     case (c, Nil) => List((c.toString, s.length-1))
                   }
        .dropRight(1)
        .map(_.head)
res12: scala.collection.immutable.IndexedSeq[List[(String, Int)]] =
           Vector((cheesecake,0),
                  (heesecake,1),
                  (eesecake,2),
                  (esecake,3),
                  (secake,4),
                  (ecake,5),
                  (cake,6),
                  (ake,7),
                  (ke,8),
                  (e,9)
                )
scala> def suffix(x: String): List[String] = x.toList match {
     |    case Nil             => Nil
     |    case xxs @ (_ :: xs) => xxs.mkString :: suffix(xs.mkString)
     | }
suffix: (x: String)List[String]

scala> def f(x: String): List[(String, Int)] = suffix(x).zipWithIndex
f: (x: String)List[(String, Int)]
scala> f("cheesecake")
res10: List[(String, Int)] = List((cheesecake,0), (heesecake,1), (eesecake,2), 
            (esecake,3), (secake,4), (ecake,5), (cake,6), (ake,7), (ke,8), (e,9))