从文本中获取矩阵的功能性方法(Functional way to get a matrix from text)

编程入门 行业动态 更新时间:2024-10-14 22:17:21
从文本中获取矩阵的功能性方法(Functional way to get a matrix from text)

我试图解决一些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 }

但我真的觉得这是错误的路要走,因为:

我为每一行使用了功能List结构,然后将其转换为数组。 整个代码似乎少得多效率 我发现它比python解决方案更不雅,更不可读。 哪些地图功能对哪些地图进行操作比较困难,因为它们都使用相同的语义。

什么是正确的功能方式来做到这一点?

I'm trying to solve some Google Code Jam problems, where an input matrix is typically given in this form:

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

where each element of the matrix is composed of, say, three integers. So this example should be converted to

#!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), )

An imperative solution would be of the form

#!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)

A functional solution I've thought of is

#!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 }

But I really feel it's the wrong way to go because:

I'm using the functional List structure for each line, and then convert it to an array. The whole code seems much less efficeint I find it longer less elegant and much less readable than the python solution. It is harder to which of the map functions operates on what, as they all use the same semantics.

What is the right functional way to do that?

最满意答案

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)) 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

And to print the result:

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))

with the assumptions:

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

To produce an array tabulate fits better:

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))

更多推荐

本文发布于:2023-07-17 13:59:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1145592.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:矩阵   功能   方法   文本中   matrix

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!