显示列表中多次出现的项目,sml

显示列表中多次出现的项目,sml,sml,smlnj,ml,Sml,Smlnj,Ml,我试图显示列表中元素的所有多次出现的索引 标准毫升 但我的代码显示的是空列表:( 这是我的代码: fun index(item, xs,ys) = let fun index'(m, nil , ys) = ( SOME (ys) ) | index'(m, x::xr , ys) = if x = item then( (ys @ [m]); index'(m + 1, xr , ys) ) else index'(m + 1, xr,ys) in index'(0

我试图显示列表中元素的所有多次出现的索引

标准毫升

但我的代码显示的是空列表:(

这是我的代码:

    fun index(item, xs,ys) =
let
fun index'(m, nil , ys) = (
  SOME (ys) )
| index'(m, x::xr , ys) = if x = item then(
  (ys @ [m]);
  index'(m + 1, xr , ys)
  )
  else index'(m + 1, xr,ys)
in
index'(0, xs , ys)
end;


index(1,[1,2,1,4,5,1],[]);
你能帮我吗?

第一件事:

  • 索引应包含两个参数:要查找的元素和要在其中查找的列表。
    累加参数属于辅助函数
  • 总是产生一些东西而从不产生任何东西是没有意义的
  • 让我们先把这些修好

    fun index (item, xs) =
        let
            fun index'(m, nil , ys) = ys
              | index'(m, x::xr, ys) = if x = item then(
                                           (ys @ [m]);
                                           index'(m + 1, xr , ys)
                                       )
                                       else index'(m + 1, xr,ys)
        in
            index'(0, xs, [])
    end;
    
    现在,在使用
    索引时,不需要传递额外的累加器参数
    除了
    []
    之外,也不可能从别的东西开始

    你的下一个主要问题是

    (ys @ [m]);
    index'(m + 1, xr , ys)
    
    它首先创建列表
    ys@[m]
    ,立即将其丢弃,然后生成其结果
    index'(m+1,xr,ys)
    ,这正是
    else
    分支所做的

    也就是说,条件等价于

    if x = item
    then index'(m + 1, xr, ys)
    else index'(m + 1, xr, ys)
    
    fun index'(m, nil, ys) = ys
      | index'(m, x::xr, ys) = index'(m + 1, xr, ys)
    
    因此,
    index'
    相当于

    if x = item
    then index'(m + 1, xr, ys)
    else index'(m + 1, xr, ys)
    
    fun index'(m, nil, ys) = ys
      | index'(m, x::xr, ys) = index'(m + 1, xr, ys)
    
    由于您总是传递原始的
    ys
    ,并且它是
    []
    开始的,因此结果总是
    []

    您需要做的是将扩展列表传递给递归,以便在递归终止时它可以成为结果。
    重命名累加器
    ys
    ,使其用途更清楚:

    fun index (item, xs) =
        let
            fun index'(i, nil, accumulator) = accumulator
              | index'(i, x::xr, accumulator) = if x = item
                                                then index' (i + 1, xr, accumulator @ [i])
                                                else index' (i + 1, xr, accumulator)
        in
            index'(0, xs, [])
    end;
    
    这是低效的,因为重复将元素追加到列表的后面。
    反向累积是很常见的,当您完成时,请更正它。
    (这“感觉”效率低下,但事实并非如此。)


    请缩进并格式化代码。