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

时间:2012-11-27 18:14:48

标签: scala recursion burrows-wheeler-transform

我一直在努力尝试在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|^

我一直在盯着这一段时间,虽然问题应该是相当直接的,但我似乎无法弄明白。你能发现我做错了吗?

2 个答案:

答案 0 :(得分:3)

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

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) 

答案 1 :(得分:2)

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

newString :: transformString(string, splitIndex - 1)

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