arrays - 从文本中获取矩阵的函数式方法

标签 arrays scala functional-programming matrix

我正在尝试解决一些 Google Code Jam 问题,其中输入矩阵通常以这种形式给出:

2 3 #matrix dimensions
1 2 3 4 5 6 7 8 9 # all 3 elements in the first row
2 3 4 5 6 7 8 9 0 # each element is composed of three integers

其中矩阵的每个元素都由三个整数组成。所以这个例子应该转换成

#!scala
Array(
     Array(A(1,2,3),A(4,5,6),A(7,8,9),
     Array(A(2,3,4),A(5,6,7),A(8,9,0),
)

命令式解决方案的形式是

#!python
input = """2 3
1 2 3 4 5 6 7 8 9
2 3 4 5 6 7 8 9 0
"""
lines = input.split('\n')
class Aclass:
    def __init__(self,a,b,c):
        pass

print lines[0]
m,n = (int(x) for x in lines[0].split())
array = []
row = []
A = []
for line in lines[1:]:
    for elt in line.split():
        A.append(elt)
        if len(A)== 3:
            row.append(Aclass(A[0],A[1],A[2]))
            A = []
    array.append(row)
    row = []

from pprint import pprint
pprint(array)

我想到的一个功能性解决方案是

#!scala
def splitList[A](l:List[A],i:Int):List[List[A]] = {
  if (l.isEmpty) return List[List[A]]()
  val (head,tail) = l.splitAt(i)
  return head :: splitList(tail,i)
}

def readMatrix(src:Iterator[String]):Array[Array[TrafficLight]] = {
  val Array(x,y) = src.next.split(" +").map(_.trim.toInt)
  val mat = src.take(x).toList.map(_.split(" ").
          map(_.trim.toInt)).
          map(a => splitList(a.toList,3).
                map(b => TrafficLight(b(0),b(1),b(2))
                 ).toArray
                ).toArray
    return mat
  }

但我真的觉得这是错误的方式,因为:

  1. 我正在为每一行使用功能性 List 结构,然后将其转换为数组。整个代码似乎效率低得多
  2. 我发现它比 python 解决方案更不优雅,可读性也更差。哪个映射函数对什么进行操作更难,因为它们都使用相同的语义。

什么是正确的功能方法?

最佳答案

val x = """2 3
1 2 3 4 5 6 7 8 9
2 3 4 5 6 7 8 9 0
"""

val a = x split "\n" map (_.trim.split(" "))
val rows = a(0)(0).toInt
val columns = a(0)(1).toInt

val matrix = (a drop 1) map (_ grouped columns toList) toList

并打印结果:

matrix.map(_.map(_.mkString("(",",",")")).mkString("(",",",")")).mkString("\n")

res1: String =
((1,2,3),(4,5,6),(7,8,9))
((2,3,4),(5,6,7),(8,9,0))

假设:

assert(rows == matrix.length)
assert(matrix.forall(_.forall(_.size == columns))) 

生成数组 tabulate 更合适:

val a = x split "\n" map (_.trim.split(" "))
val rows = a(0)(0).toInt
val columns = a(0)(1).toInt
val matrix = Array.tabulate(rows, a(1).size / columns, columns)(
  (i,j,k) => a(i +  1)(j * columns + k))

关于arrays - 从文本中获取矩阵的函数式方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2522904/

相关文章:

java - 字符串数组错误

scala - 是否可以在 Actor 中使用 Akka 调度程序?

javascript - 任何 JavaScript 语句都是表达式吗?

javascript - JS es2015 中未知的函数格式

c# - 为什么我不能使用扩展方法隐式转换委托(delegate)?

Java arraycopy 二维数组的特定区域

javascript - 使用 Javascript 将 <pre> 中的内容放入数组中

javascript - 我可以使用什么查询从选定键值的本地存储中获取数据

scala - 使用猫从 future 中提取值(value)

scala - Web UI(http://localhost:8088)未显示Spark应用程序