递归在scala中创建字符串的所有旋转

Posted

技术标签:

【中文标题】递归在scala中创建字符串的所有旋转【英文标题】:Recursive create all rotations of string in scala 【发布时间】:2012-11-27 18:14:47 【问题描述】:

我一直在尝试在wikipedia 上重新创建 Burrows-Wheeler 变换的示例。为了增加乐趣,我试图通过递归策略来做到这一点。但是,我陷入了第一步,创建了字符串的所有旋转。这是我的代码:

object SimpleBW extends App 

  val string = "^BANANA|"

  val list = tranformStringStart(string)
  list.foreach(println)

  def tranformStringStart(string: String): List[String] =  transformString(string, string.length) 

  def transformString(string: String, splitIndex: Int): List[String] = 
    if (splitIndex == 0) 
      // Recursion base case
      Nil
     else 
      val (firstString, secondString) = string.splitAt(splitIndex)
      val newString = secondString + firstString
      newString :: transformString(secondString + firstString, splitIndex - 1)
    
  


这会生成以下输出:

^BANANA|
|^BANANA
NA|^BANA
ANANA|^B
A|^BANAN
BANANA|^
NANA|^BA
ANA|^BAN

这类似于***的例子,但不完全相同,我似乎无法弄清楚为什么。根据示例,输出应如下所示:

^BANANA|
|^BANANA
A|^BANAN
NA|^BANA
ANA|^BAN
NANA|^BA
ANANA|^B
BANANA|^

我已经盯着这个看了一段时间了,虽然问题应该是相当直接的,但我似乎无法弄清楚。你能发现我做错了什么吗?

【问题讨论】:

【参考方案1】:

这是一个较短的函数,它不使用递归,但在计算中也是如此。

def transformString(s:String):List[String] = 
  for(i <- s.length until 0 by - 1 toList) yield s.drop(i)+ s.take(i)

另一个:

def transformString(s:String):List[String] = s.inits.toList zip(s.tails.toSeq.reverse) map(z=> z._2+z._1) 

【讨论】:

【参考方案2】:

当您将 splitIndex 一个字符移到前面时,您必须将其应用于原始字符串:

newString :: transformString(string, splitIndex - 1)

另一种解决方案是删除拆分索引参数并始终拆分最后一个字符,但是您必须再次将其应用于转换后的字符串。

【讨论】:

以上是关于递归在scala中创建字符串的所有旋转的主要内容,如果未能解决你的问题,请参考以下文章

如何从字符串中提取值以在 Scala 中创建案例类实例

字谜递归Scala

在字符串中创建所有字母替换组合

Unix 上的递归 mkdir() 系统调用

如何从 Scala 中的 DataFrame 在 Spark 中创建分布式稀疏矩阵

如何在 MSSQL 2005 中创建递归查询?