【问题标题】:A better algorithm to find the next palindrome in Scala在 Scala 中找到下一个回文的更好算法
【发布时间】:2015-06-20 13:25:17
【问题描述】:

问题来了:

如果从左到右和从右到左读取时,它在十进制系统中的表示相同,则称为回文。对于给定的不超过 1000000 位的正整数 K,将大于 K 的最小回文数的值写入输出。数字始终显示不带前导零。

输入:第一行包含整数 t,即测试用例的数量。整数 K 在接下来的 t 行中给出。

输出:对于每个K,输出大于K的最小回文数。示例

输入:

2 808 第2133章

输出:

818 2222

还有我的Scala 代码:

object Pro_5 {

  // find the next palindrome larger than K
  def findPalindrome(input: String) = {
    // start from (k + 1)
    val tmp = (BigInt(input) + 1).toString

    val length = tmp.length
    val mid = length / 2

    val left = tmp.substring(0, length >> 1)
    val right = tmp.substring(length >> 1, length)

    // whether continue for loop
    var flag = true
    // half of the result
    var res = ""

    for (i <- 0 until mid if flag) {
      if (left(i) > right(mid - 1)) {
        res = left
        flag = false
      } else if (left(i) < right(mid - 1)) {
        res = (BigInt(left) + 1).toString()
        flag = false
      }
    }

    if (length % 2 == 0) {
      res + res.reverse
    } else {
      res + tmp(mid) + res.reverse
    }

  }

  // get K
  def getInput(times: Int) = {
    for (time <- 0 until times) yield readLine()
  }

  def main(args: Array[String]) {
    // get compute times
    val times = readInt()
    getInput(times).map(findPalindrome(_)).foreach(println)
  }

}

我从Mark Peters's answer学到了一些东西

但是当我在SPOJ 中运行它时,我仍然得到了time limit exceeding error.

你能帮我改进算法吗?

欢迎任何答案...

【问题讨论】:

  • 它实际上在第一次测试中失败了findPalindrome("808") ---> "808"
  • @harshtuna 你是对的,它失败了。我会改进我的代码。

标签: algorithm scala


【解决方案1】:

Mark Peters's answer 确实已经解释了一个好的算法

所以这只是正确实施的问题。这里有一个提示如何改进代码,减少 java 并支持奇数计数

def split(s: String) = {
  val mid = (s.length + 1) / 2
  val left = s.substring(0, mid)
  val right = s.substring(s.length - mid, s.length)
  (left, right)
}

//right string should be reversed
@tailrec
def compareFromIndex(left: String, right: String, i: Int): String = {
  if (i < 0) left
  if (left(i) > right(i)) left
  else if (left(i) < right(i)) (BigInt(left) + 1).toString()
  else compareFromIndex(left, right, i - 1)
}

val half = compareFromIndex(left, right.reverse, left.length - 1)

这几乎是完整的实现 :) 只需将正确的输入传递给 split 函数。并从计算的“一半”中制作完整的回文。祝你好运!

【讨论】:

  • @hashtuna 这仅适用于偶数长度的数字。当数字为奇数时,如果右侧字符大于左侧字符,则必须增加中间的数字。
  • @PeterNeyens 它确实适用于奇数数:split("809") -> ("80", "09")。在我的解决方案中,左右两边都包含中间字符。处理较少的特殊情况。然后compareFromIndex("80", "90", 1) -> "81"。最后一步是“81”->“818”。瞧! :)
  • @hashtuna 你是对的。将一半变成回文时,您只需处理奇数情况。
猜你喜欢
  • 2011-12-17
  • 2017-11-27
  • 2021-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多