前言:
笔者最近在学习Scala,通过Scala刷leetcode算法来掌握语法。但leetcode对Scala极不友好,且测试样例所需时间非常多。因此需要使用idea进行辅助。但idea并没有封装输入,因此数组的输入封装就成了大问题
比如[1, 2, 3],若要能让Scala识别,需要改写为Array(1, 2, 3)。如果数组数量增多,维数提高,刷题效率就会收到影响,因此编写本文,提供一个工具函数解决转换问题
思路
对于leetcode题目,每一题的数组维数已经固定死了。且数组最大维数基本都是二维。因此我们可以单独封装两个函数convertOneDim
,convertTwoDim
但是因为方法无法提前预知返回的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(" "))
}