编写Scala工具函数,将leetcode多维数组的String表现形式转换为Array

发布于:2024-05-17 ⋅ 阅读:(135) ⋅ 点赞:(0)

前言:

  • 笔者最近在学习Scala,通过Scala刷leetcode算法来掌握语法。但leetcode对Scala极不友好,且测试样例所需时间非常多。因此需要使用idea进行辅助。但idea并没有封装输入,因此数组的输入封装就成了大问题

  • 比如[1, 2, 3],若要能让Scala识别,需要改写为Array(1, 2, 3)。如果数组数量增多,维数提高,刷题效率就会收到影响,因此编写本文,提供一个工具函数解决转换问题

思路

对于leetcode题目,每一题的数组维数已经固定死了。且数组最大维数基本都是二维。因此我们可以单独封装两个函数convertOneDimconvertTwoDim

但是因为方法无法提前预知返回的Array需要的泛型是什么,因此需要封装一层处理为具体类型的方法

convertOneDim

object ArrayConverter {
    private def toInt: String => Int = (s: String) => s.toInt
    private def toStr: String => String = s => s

    /**
     * 转换为一维数组
     * @param input 输入, 形如[1, 2, 3, 4, 5], 如果格式错误, 转换异常别怪我
     * @param handler 转换方法
     * @return
     */
    private def convertOneDim[_](input: String, handler: String=>_): Array[_] = {
        input.substring(1, input.length - 1).split(",").map(handler)
    }

    // 转换为一维数组, 且元素为Int
    def convertOneDimInt(input: String): Array[Int] = {
        convertOneDim[Int](input, toInt).map(_.asInstanceOf[Int])
    }

    // 转换为一维数组, 且元素为String
    def convertOneDimStr(input: String): Array[String] = {
        convertOneDim[String](input, toStr).map(_.asInstanceOf[String])
    }

    /**
     * 转换为二维数组
     * @param input 输入, 形如[[1, 2], [3, 4], [5, 6]], 如果格式错误, 转换异常别怪我
     * @param handler 转换方法
     * @return
     */
    private def convertTwoDim[_](input: String, handler: String=>Any): Array[Array[_]] = {
        // 去除第一个维度的[], 形成如[1,2],[3,4]这样的str
        val str: String = input.substring(1, input.length - 1)
        var start: Int = 0
        val ans: mutable.ArrayBuffer[Array[_]] = ArrayBuffer[Array[_]]()
        // 分割str, 取出单独的数组
        for (end <- 0 until str.length) {
            val c: Char = str.charAt(end)
            if (c == '[') start = end
            else if (c == ']') ans.append(convertOneDim(str.substring(start, end + 1), handler))
        }
        ans.toArray
    }

    // 转换为一维数组, 且元素为Int
    def convertTwoDimInt(input: String): Array[Array[Int]] = {
        convertTwoDim[Int](input, toInt).map(_.map(_.asInstanceOf[Int]))
    }

    // 转换为二维数组, 且元素为String
    def convertTwoDimStr(input: String): Array[Array[String]] = {
        convertTwoDim[String](input, toStr).map(_.map(_.asInstanceOf[String]))
    }
}

convertOneDim编写思路非常简单,我们将左右两侧的[ ]去掉后,按照,分割。对分割后的每一个元素执行handle转换操作,最终得到Array

考虑到方法的通用性,我们无法确定我们要将字符串转换为Int, 还是String。因此用_代替。另外,我们将转换功能下放给调用方操作。在ArrayConverter内部封装toInt, toStr函数,以供调用方使用

具体来说,封装convertOneDimInt, convertOneDimStr方法,将convertOneDim返回结果强转,具体使用方式如下

object Test1 extends App {
    val array: Array[Int] = ArrayConverter.convertOneDimInt("[1,2,3,4,5]")
    println(array.mkString(" "))
    val array1: Array[String] = ArrayConverter.convertOneDimStr("[1,2,3,4,5]")
    println(array1.mkString(" "))
}

convertTwoDim

object ArrayConverter {
    private def toInt: String => Int = (s: String) => s.toInt
    private def toStr: String => String = s => s

    /**
     * 转换为二维数组
     * @param input 输入, 形如[[1, 2], [3, 4], [5, 6]], 如果格式错误, 转换异常别怪我
     * @param handler 转换方法
     * @return
     */
    private def convertTwoDim[_](input: String, handler: String=>Any): Array[Array[_]] = {
        // 去除第一个维度的[], 形成如[1,2],[3,4]这样的str
        val str: String = input.substring(1, input.length - 1)
        var start: Int = 0
        val ans: mutable.ArrayBuffer[Array[_]] = ArrayBuffer[Array[_]]()
        // 分割str, 取出单独的数组
        for (end <- 0 until str.length) {
            val c: Char = str.charAt(end)
            if (c == '[') start = end
            else if (c == ']') ans.append(convertOneDim(str.substring(start, end + 1), handler))
        }
        ans.toArray
    }

    // 转换为二维数组, 且元素为Int
    def convertTwoDimInt(input: String): Array[Array[Int]] = {
        convertTwoDim[Int](input, toInt).map(_.map(_.asInstanceOf[Int]))
    }

    // 转换为二维数组, 且元素为String
    def convertTwoDimStr(input: String): Array[Array[String]] = {
        convertTwoDim[String](input, toStr).map(_.map(_.asInstanceOf[String]))
    }
}

convertOneDim的编写思路就是降维,先将二维将为成一维,然后调用一维处理函数

object Test2 extends App {
    val array: Array[Array[Int]] = ArrayConverter.convertTwoDimInt("[[2,1,1],[1,1,0],[0,1,1]]")
    println(array.mkString(" "))
    val array1: Array[Array[String]] = ArrayConverter.convertTwoDimStr("[[2,1,1],[1,1,0],[0,1,1]]")
    println(array1.mkString(" "))
}

完整代码

import scala.collection.mutable
import scala.collection.mutable.ArrayBuffer

object ArrayConverter {
    private def toInt: String => Int = (s: String) => s.toInt
    private def toStr: String => String = s => s

    /**
     * 转换为一维数组
     * @param input 输入, 形如[1, 2, 3, 4, 5], 如果格式错误, 转换异常别怪我
     * @param handler 转换方法
     * @return
     */
    private def convertOneDim[_](input: String, handler: String=>_): Array[_] = {
        input.substring(1, input.length - 1).split(",").map(handler)
    }

    // 转换为一维数组, 且元素为Int
    def convertOneDimInt(input: String): Array[Int] = {
        convertOneDim[Int](input, toInt).map(_.asInstanceOf[Int])
    }

    // 转换为一维数组, 且元素为String
    def convertOneDimStr(input: String): Array[String] = {
        convertOneDim[String](input, toStr).map(_.asInstanceOf[String])
    }

    /**
     * 转换为二维数组
     * @param input 输入, 形如[[1, 2], [3, 4], [5, 6]], 如果格式错误, 转换异常别怪我
     * @param handler 转换方法
     * @return
     */
    private def convertTwoDim[_](input: String, handler: String=>Any): Array[Array[_]] = {
        // 去除第一个维度的[], 形成如[1,2],[3,4]这样的str
        val str: String = input.substring(1, input.length - 1)
        var start: Int = 0
        val ans: mutable.ArrayBuffer[Array[_]] = ArrayBuffer[Array[_]]()
        // 分割str, 取出单独的数组
        for (end <- 0 until str.length) {
            val c: Char = str.charAt(end)
            if (c == '[') start = end
            else if (c == ']') ans.append(convertOneDim(str.substring(start, end + 1), handler))
        }
        ans.toArray
    }

    // 转换为二维数组, 且元素为Int
    def convertTwoDimInt(input: String): Array[Array[Int]] = {
        convertTwoDim[Int](input, toInt).map(_.map(_.asInstanceOf[Int]))
    }

    // 转换为二维数组, 且元素为String
    def convertTwoDimStr(input: String): Array[Array[String]] = {
        convertTwoDim[String](input, toStr).map(_.map(_.asInstanceOf[String]))
    }
}

object Test1 extends App {
    val array: Array[Int] = ArrayConverter.convertOneDimInt("[1,2,3,4,5]")
    println(array.mkString(" "))
    val array1: Array[String] = ArrayConverter.convertOneDimStr("[1,2,3,4,5]")
    println(array1.mkString(" "))
}

object Test2 extends App {
    val array: Array[Array[Int]] = ArrayConverter.convertTwoDimInt("[[2,1,1],[1,1,0],[0,1,1]]")
    println(array.mkString(" "))
    val array1: Array[Array[String]] = ArrayConverter.convertTwoDimStr("[[2,1,1],[1,1,0],[0,1,1]]")
    println(array1.mkString(" "))
}


网站公告

今日签到

点亮在社区的每一天
去签到