在列表中找到k个不同元素的最小子序列

时间:2019-03-29 10:42:32

标签: arrays sml smlnj

我对sml非常陌生。我正在尝试编写一个简单的代码,该代码采用具有特定数字的5个位置的数组,并返回包含所有数字的最小子数组的长度。但是,我收到许多错误消息,这些错误消息在Google中找不到。谁能帮我?代码如下

 fun Min x y = if x>y then return y else return x
    local
        val a = Array.array (3,0)
        val cordela = Array.array(5,0)
        val k=0
        val front=0
        val tail=0
        val min=5
        update(cordela,0,1)
        update(cordela,1,3)
        update(cordela,2,3)
        update(cordela,3,2)
        update(cordela,4,1)
    in   
        fun loop front = 
            case k>3 of
                if sub(a,sub(cordela,front)-1) = 0 then k=k+1 else()
                update(a,sub(cordela,front)-1),sub(a,sub(cordela,front)-1)+1)
                front = front +1
            | 
                min= Min (front-tail) min
                if sub(a,sub(cordela,front)-1) = 0 then k=k-1 else()
                update(a,sub(cordela,front)-1),sub(a,sub(cordela,front)-1)-1)
                tail=tail+1

            if 5>front then loop front+1 else min
    end 

我收到的错误消息是:

pl2.sml:16.13-16.15 Error: syntax error: replacing  OF with  LBRACKET
pl2.sml:18.36 Error: syntax error: inserting  LPAREN
pl2.sml:20.4 Error: syntax error: replacing  BAR with  EQUALOP
pl2.sml:22.5 Error: syntax error: inserting  LPAREN
pl2.sml:26.4 Error: syntax error: inserting  LPAREN
pl2.sml:27.2 Error: syntax error found at END

编辑:我正在尝试用sml编写此代码。它是用C ++编写的

while(front < N){
        if( k < K ){
            if ( e[cordela[front]-1] == 0 ) k += 1;
            e[cordela[front]-1] +=1;
            front++ ;
        }
        else{
            min = MIN(front - tail ,min);
            if ( e[cordela[tail]-1] ==1 ) k -= 1;
            e[cordela[tail]-1] -= 1;
            tail++;
        }
    }

1 个答案:

答案 0 :(得分:2)

正如John Coleman所说,SML / NJ不会给出非常有用的错误消息。您可以尝试使用install Moscow ML代替,因为它可以提供更好的错误消息。不幸的是,此代码在语法级别上有些问题,这使编译器很难给出有意义的错误。以下是正确使用语法的一些提示,以便您可以专注于算法问题:

  • Don't use local, use let
  • 将每个(与一个)相匹配;您有太多)个电话。
  • fun loop ... = ...let内声明in
  • 完成此操作后,用于解决问题的函数的模板可能如下所示:

    fun smallest_subarray (needles : Array.array, haystack : Array.array) =
        let
          val ... = ...
          fun loop ... = ...
        in
          if Array.length needles > Array.length haystack
          then ...
          else loop ...
        end
    

如果无法解决问题,该函数将返回什么? ~1NONE

如果要将C ++程序转换为SML,请尝试以明显的方式将哪些标识符作为函数的参数,并以逻辑方式命名它们,从而包括函数部分。我不知道cordelaek是什么,或者N是输入数组大小的函数还是一个常数。

由于SML中的惯用解决方案使用递归(调用自身的函数)而不是迭代(while),因此您既要处理非平凡的算法问题,又要处理另一个范式。尝试解决一个类似但更简单的问题,该算法更简单,并应用递归范式。

例如,尝试编写一个使用二进制搜索在排序数组中查找元素位置的函数:

fun find x arr =
    let
      fun loop ... = ...
    in
      loop ...
    end

loop函数将搜索范围(例如ij)作为参数,如果在位置{处发现SOME i,则返回x {1}}或i。您可以通过尝试编写一个函数来确定输入数组NONE是否在另一个输入数组needles中按照{给定的顺序),将问题扩展到原始问题的方向。 {1}}。您可以先假设haystackneedles已排序,然后再假设它们没有排序。