Java 将SML功能设置为;齐头并进“;任意深度的列表

Java 将SML功能设置为;齐头并进“;任意深度的列表,java,recursion,functional-programming,pattern-matching,sml,Java,Recursion,Functional Programming,Pattern Matching,Sml,我正在尝试将Java代码中的嵌套for循环转换为SML。我将有一个格式为[[a,b,c],[d,e,f],[g,h,I]]的列表,我希望这个函数给我一个形式为[[a,d,g],[b,e,h],[c,f,I]]的列表。每个列表的长度会有所不同,我需要避免使用任何可变的数据类型。到目前为止,我的代码是这样的——底部的pointFromList获取每个内部列表,并将其放入我在别处定义的记录中 我遇到的问题是下面的代码没有终止。从调试输出来看,它在所有的zipElement([],xs::xss,acc

我正在尝试将Java代码中的嵌套for循环转换为SML。我将有一个格式为[[a,b,c],[d,e,f],[g,h,I]]的列表,我希望这个函数给我一个形式为[[a,d,g],[b,e,h],[c,f,I]]的列表。每个列表的长度会有所不同,我需要避免使用任何可变的数据类型。到目前为止,我的代码是这样的——底部的
pointFromList
获取每个内部列表,并将其放入我在别处定义的记录中

我遇到的问题是下面的代码没有终止。从调试输出来看,它在所有的
zipElement([],xs::xss,accY,accX)
调用中都可以正常工作,但在之后的某个地方它会中断。我是SML的新手,我完全被难住了

fun zipListToPoints (featuress : real list list) = 
    let
    fun zipElement ([], [], accY, []) = 
        accY
      | zipElement ([], [], accY, accX) =      
        zipElement(rev(accX), rev(accY), [], [])
      | zipElement ([], xs::xss, accY, accX) = 
        zipElement([], xss, [hd(xs)]::accY, tl(xs)::accX)
      | zipElement (ys::yss, xs::xss, accY, accX) =
        zipElement (yss, xss, (hd(xs)::ys)::accY, tl(xs)::accX)
    val numFeatures = length(hd(featuress))
    val zippedList = zipElement([], featuress, [], [])
    in
    map pointFromList zippedList
    end
end 
更大的背景是我有一个记录类型
,带有标签
功能:真实列表
。为了在对数据进行一些分析之前对其进行规范化,我需要对每个点的
特征
列表的第I个元素执行操作。最初的Java如下所示:

for(i=0;i<Points.length(); i++){
    oneFeature = new float[Points.getNumberOfFeatures()];

    for(j=0; j<Points.getNumberOfFeatures(); j++){
    oneFeature[j] = Points[j].getFeature(i);
    }

    normalizedData = new float[Points.getNumberOfFeatures()];
    normalizedData = normalize(oneFeature);

    for(k=0; k<Points.length(); k++){
    Points[k].setFeatureList(normalizedData[k]);
    }
}

(抱歉,我的SML缩进有点搞砸了!)

下面是一个关于内部
zipElement
所有学分归丹·格罗斯曼所有

exception BadTriple
fun zip3 list_triple =
  case list_triple of
      ([],[],[]) => []
     | (hd1::tl1,hd2::tl2,hd3::tl3) => (hd1,hd2,hd3)::zip3(tl1,tl2,tl3)
     | _ => raise BadTriple

我希望您能自己找到将元组转换为列表的方法。

如果您的列表是规则的(列表中的每个列表都具有相同的长度),那么您描述的内容听起来像是矩阵变换。使用标准的ML列表组合器很容易实现这一点。例如:

fun transpose [] = []
  | transpose (xss as (xs::_)) =
    List.tabulate (length xs, fn row => map (fn xs => List.nth (xs, row)) xss)
还有一个示范:

- val m = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]];
> val m = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]] : int list list
- transpose m;
> val it = [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]] : int list list
可以调整此
fn row=>map(fn xs=>List.nth(xs,row))
helper函数,使其在给定行未满时接受。但是,如果所有行的长度都不相等,则需要先找到其中最长的一行,以避免在大于第一行长度的位置上丢弃元素

更新:对于大型矩阵,上述运行时间可能无法计算。下面是另一种定义
转置
的方法,这样以前转置的元素就不会被反复访问:

(* Written without pattern matching *)
fun transpose [] = []
  | transpose xs =
    if null (hd xs)
    then nil
    else map hd xs :: transpose (map tl xs)

(* Written with pattern matching *)
fun transpose [] = []
  | transpose ([]::_) = []
  | transpose xss = map hd xss :: transpose (map tl xss)

我想我会遵循这一点。我尝试走这条路线的原因之一——一个遍历两个列表的尾部递归函数——是因为我假设List.nth花费了O(n)个时间,给出了整个过程。。。我想是时间吧?使用n=length(xs)和m=length(xss),因为对于xss中的每个列表,对xs中的每个项调用List.nth一次。我想通过列表一次就可以完成全部工作。无论如何,我会搜索SML矩阵转置。是的,你是对的
List.nth
确实不必要地多次迭代相同的元素。我提供了一个版本的
transpose
,它不受此影响。
(* Written without pattern matching *)
fun transpose [] = []
  | transpose xs =
    if null (hd xs)
    then nil
    else map hd xs :: transpose (map tl xs)

(* Written with pattern matching *)
fun transpose [] = []
  | transpose ([]::_) = []
  | transpose xss = map hd xss :: transpose (map tl xss)