【发布时间】:2011-02-01 03:33:38
【问题描述】:
我正在尝试解决一些 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 解决方案更不优雅,更不可读。哪个映射函数对什么进行操作更难,因为它们都使用相同的语义。
什么是正确的功能方法?
【问题讨论】:
-
那么 scala 会是语言吗?如果不是,您使用的是什么语言?我知道您正在寻求一种功能性的方法来做到这一点,但是一个好的课程可能会为您提供更好的解决方案
-
@thecoshman 语言只是我传达 FP 想法的管道。出于实际目的,我不需要它,我只是在学习 FP。我碰巧知道 Scala 而不是 Haskell,所以我使用了它,但我可以在每一种功能足够的语言中做到这一点(即使 python 也很实用)。也许这个任务确实更适合命令式/OO 方法,但我仍在寻找最佳的功能解决方案。
-
3x2矩阵的数据会是什么样子?
-
@Thomas 每个都是使用三个变量的数据结构。假设它是一个三元组数组。
-
@Thomas Jung 矩阵是(通常)二维数字网格。它们用于数学,非常方便地表示一组操作,例如,将 y 轴向上移动十个空格,围绕 x 轴旋转 60 度,沿 z-y 轴缩放 0.5。遗憾的是,cmets 不允许我使用新线,所以我无法向您展示数学中的新线。
标签: arrays scala functional-programming matrix