找到On Screen Keyboard scala的击键

时间:2017-05-11 15:40:02

标签: algorithm scala mergesort fold foldleft

我正在尝试使用Scala来解决最近的面试问题。

你有一个屏幕键盘,它是一个6行,每列5列的网格。使用从A到Z的字母和空白区域首先排列在网格行中。

您可以在屏幕键盘上使用此键输入单词..按左,右,上,下或OK键使用电视遥控器键入每个字符。

问题:给定输入字符串,找到需要在遥控器上按下以键入输入的按键序列。

可以在

找到代码实现

https://github.com/mradityagoyal/scala/blob/master/OnScrKb/src/main/scala/OnScrKB.scala

我试图用三种不同的方法来解决这个问题。

  1. 简单的forldLeft。

    def keystrokesByFL(input: String, startChar: Char = 'A'): String = {
    val zero = ("", startChar)
    //(acc, last) + next => (acc+ aToB , next) 
    def op(zero: (String, Char), next: Char): (String, Char) = zero match {
      case (acc, last) => (acc + path(last, next), next)
    }
    val result = input.foldLeft(zero)(op)
    result._1
    

    }

  2. 分而治之 - 使用分而治之的机制。该算法类似于合并排序。 *如果长度> 1,我们将输入字分成两部分。 3 *我们递归调用子程序以从分割中获得左半部分和右半部分的路径。 *最后..我们将第一个+键击的键击从第一个字符串的结尾添加到第二个字符串的开始+第二个键击。 *基本上我们将输入字符串分成两个较小的一半,直到我们达到大小4.对于小于4,我们使用向右折叠。

    def keystrokesByDnQ(input: String, startChar: Char = 'A'): String = {
    def splitAndMerge(in: String, startChar: Char): String = {
      if (in.length() < 4) {
        //if length is <4 then dont split.. as you might end up with one side having only 1 char. 
        keystrokesByFL(in, startChar)
      } else {
        //split
        val (x, y) = in.splitAt(in.length() / 2)
        splitAndMerge(x, startChar) + splitAndMerge(y, x.last)
      }
    }
    splitAndMerge(input, startChar)
    

    }

  3. 折叠 - 使用基础操作关联的属性(但不是可交换的)。 *例如..键击(“ABCDEFGHI”,startChar ='A')==击键(“ABC”,startChar ='A')+击键(“DEF”,'C')+击键(“GHI”, 'F')

    def keystrokesByF(input: String, startChar: Char = 'A'): String = {
      val mapped = input.map { x => PathAcc(text = "" + x, path = "") } // map each character in input to case class PathAcc("CharAsString", "")
      val z = PathAcc(text = ""+startChar, path = "") //the starting char. 
    
      def op(left: PathAcc, right: PathAcc): PathAcc = {
      PathAcc(text = left.text + right.text, path = left.path + path(left.text.last, right.text.head) + right.path)
      }
      val foldresult = mapped.fold(z)(op)
    
      foldresult.path
    }
    
  4. 我的问题: 1.分而治之的方法是否比折叠更好?

    1. 折叠和分割并且比foldLeft更好地征服(针对此特定问题)

    2. 有没有办法可以代表分而治之的方法或折叠方法作为Monad?我可以看到相关法律得到满足......但是我无法弄清楚这里是否存在幺半群......如果是的话......它对我有什么影响?

    3. 分裂和征服是否是针对此特定问题的最佳方法?

    4. 哪种方法更适合火花?

    5. 欢迎提出任何建议。

0 个答案:

没有答案