【问题标题】:Scala: how to find maximum continuous occurrence of a character in file?Scala:如何找到文件中字符的最大连续出现次数?
【发布时间】:2019-12-04 17:37:54
【问题描述】:

问题: 假设,我有一个包含类似数据的文本文件

TATTGCTTTGTGCTCTCACCTCTGATTTTACTGGGGGCTGTCCCCCACCACCGTCTCGCTCTCTCTGTCA
AAGAGTTAACTTACAGCTCCAATTCATAAAAAAAAAAAAAAATTAGGAGTGTTTAAATCCAAACCCCTCA
GATGGCTCTCTAACTCGCCTGACAAATTTACCCGGACTCCTACAGCTATGCATATGATTGTTTACAGCCT

我想找到字符“A”的最大连续出现次数,例如“AAAA..”等。以及在文件中的哪个位置 - 比如在哪一行。

应该采取什么方法?

  val source = scala.io.Source.fromFile(filePath)
  val lines = source.getLines().filter(char => char != '\n')

  for (line <- lines) {
    //how should I do that
  }

这会给我类似的输出

AAAAAAAAAAAAAAA(line 2)

我的问题 如何在文件中的位置找到最大连续出现的字符“A”,例如“AAAA ..”等 - 比如在哪一行?

【问题讨论】:

  • 我建议您首先准确定义您期望的输出是什么,并考虑如果您是计算机,您将如何解决此类问题,然后逐步思考基本算法是什么步骤然后尝试编写代码,如果您对最后一部分有问题,您可以返回并编辑此问题以提供更多详细信息。
  • 如果字符跨越多行,您当前的方法不会将字符视为连续字符。这是预期的吗?
  • @Tom 实际上我在问正确的方法。比如我应该怎么做?让我编辑我的问题
  • @Tom 我更新了我的问题

标签: scala


【解决方案1】:

好的,首先这里如何处理一行:

 def maxInLine(line: String) = line.split("[B-Z]").toList.max

我们可以使用正则表达式来分割行。 (List(, A, , , , AA, , , , , , ,) 对于其他字符,正则表达式看起来不同。

由于字符串的最大值是字符最多的那个(如果它们相同的话),我们只需要max就可以得到一行的最大字符数。

然后得到所有行的最大值:

val (as, index) = allLines
                    .map(maxInLine)               // Get the max of a Line
                    .zipWithIndex                 // zip it - for the line number
                    .maxBy { case (l, _) => l }   // get the line that has the most A

然后我们可以这样使用结果:

println(s"$as (${as.length} As / Line ${index + 1})")

哪个打印:AAAAAAAAAAAAAAA (15 As / Line 2)

【讨论】:

    【解决方案2】:

    这里有一些方法可以找到仅由一个字符组成的最长字符串(因此不仅可以查找 'A,还可以根据需要轻松调整):

    我正在折叠每个字符,计算一些任意定义的State。这个State会在内存中保存最长的序列和当前的序列,以及各自的起始位置。

    val stream = "TATTGCTTTGTGCTCTCACCTCTGATTTTACTGGGGGCTGTCCCCCACCACCGTCTCGCTCTCTCTGTCAAAGAGTTAACTTACAGCTCCAATTCATAAAAAAAAAAAAAAATTAGGAGTGTTTAAATCCAAACCCCTCAGATGGCTCTCTAACTCGCCTGACAAATTTACCCGGACTCCTACAGCTATGCATATGATTGTTTACAGCCT".toStream
    
    case class State(longest: String, current: String, longestPos: Int, currentPos: Int)
    
    val state = stream.foldLeft(State("","", 1, 1)){case (state, c) =>
      val (current: String, curpos: Int) = if(state.current.forall(_ == c)) (state.current :+ c, state.currentPos) else (c.toString, state.currentPos+state.current.length)
      if(state.longest.length < current.length)
        State(current, current, curpos, curpos)
      else State(state.longest, current, state.longestPos, curpos)
    }
    
    println(s"longest sequence : '${state.longest}' with ${state.longest.length} chars, at position ${state.longestPos}")
    

    输出:

    longest sequence : 'AAAAAAAAAAAAAAA' with 15 chars, at position 98
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-02
      • 1970-01-01
      • 2020-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多