Найдите наименьшую подпоследовательность из k различных элементов в списке

Я супер новичок в 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. Он написан на С++

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++;
        }
    }

Сообщения об ошибках SML/NJ могут быть непрозрачными. Обратите внимание, что вам не хватает подходящего else, который не является обязательным в sml.

John Coleman 29.03.2019 11:46

@JohnColeman Я исправил операторы else, но все же ошибки появляются немного по-другому.

user7475343 29.03.2019 13:29

Ваши case не имеют смысла (где => ?). В более общем смысле вы, кажется, пытаетесь написать Java-подобный код на SML. Вы думаете слишком императивно, а не функционально. Кроме того, почему вы используете local, а не let?

John Coleman 29.03.2019 14:49

@JohnColeman Спасибо, какие улучшения я должен был внести в этот код, чтобы работать в ML

user7475343 29.03.2019 15:40

Совершенно непонятно, что вы пытаетесь сделать. Какой тип функции вы пытаетесь написать? Код очень многословен для SML, но поскольку я действительно не знаю, что вы пытаетесь сделать, я не могу дать конкретных рекомендаций. С вашей стороны много путаницы в отношении базовой семантики SML. Например. if sub(a,sub(cordela,front)-1) = 0 then k=k+1 else() не будет печатать чек. поскольку тип k=k+1 является логическим (он не заменяет k на k+1, вместо этого он сравнивает k и k+1, оценивая false), но тип () в конце — unit, а не логический.

John Coleman 29.03.2019 17:47

@JohnColeman Пожалуйста, смотрите правку

user7475343 29.03.2019 22:47

"Я пытаюсь написать этот код на sml. Он написан на c++" --- почему? Просто напишите код SML в SML. Вы пытаетесь написать императивный код на функциональном языке. Забудьте о C++. Здесь это не очень актуально. Кроме того, вы никогда четко не объясняли, что именно вы пытаетесь сделать. Что такое тип функции, которую вы пытаетесь написать?

John Coleman 30.03.2019 00:44

@JohnColeman Я пытаюсь написать функцию, которая находит длину наименьшего подмассива, содержащего все элементы большого массива. Пример: 1 2 2 3 2 2 2 3 1 Ответ: 3

user7475343 30.03.2019 11:12

Вы уверены, что имеете в виду массив, а не список? Кроме того, когда я просил тип, я искал что-то вроде int list -> int

John Coleman 30.03.2019 11:27

@JohnColeman Это может быть и то, и другое. Числа задаются как входные данные из файла.

user7475343 30.03.2019 11:29

Давайте продолжить обсуждение в чате.

user7475343 30.03.2019 11:41
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
0
11
414
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как говорит Джон Коулман, SML/NJ не выдает очень полезных сообщений об ошибках. Вместо этого вы можете попробовать установить Московское МЛ, так как это дает более качественные сообщения об ошибках. К сожалению, в этом коде есть некоторые ошибки на синтаксическом уровне, из-за чего компилятору сложно выдать осмысленную ошибку. Вот несколько советов, как правильно понять синтаксис, чтобы вы могли сосредоточиться на проблемах алгоритма:

  • Не используйте local, используйте let.
  • Сопоставьте каждый ( с ); у тебя слишком много )s.
  • Объявите 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
    

А если решения проблемы нет, что вернет функция? ~1? NONE?

Если вы пытаетесь преобразовать программу на C++ в SML, попробуйте включить функциональную часть таким образом, чтобы было очевидно, какие идентификаторы являются аргументами функции, и попытайтесь назвать их логически; Я понятия не имею, что такое cordela, e и k, является ли N функцией размера входного массива или константой.

Поскольку идиоматическое решение в SML использует рекурсию (функция, вызывающая саму себя), а не итерацию (while), вы имеете дело как с нетривиальной проблемой алгоритма а также, так и с другой парадигмой. Вместо этого попробуйте решить аналогичную, но более простую задачу, где алгоритм более тривиален, и примените парадигму рекурсии.

Например, попробуйте написать функцию, которая находит позицию элемента в отсортированном массиве с помощью бинарного поиска:

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

Функция loop примет границы поиска (например, i и j) в качестве аргумента и вернет либо SOME i, если x найден в позиции i, либо NONE. Вы можете расширить эту проблему в направлении исходной проблемы, попытавшись затем написать функцию, которая определяет, встречается ли входной массив needles в другом входном массиве haystack в порядке, указанном в needles. Вы можете сначала предположить, что needles и haystack отсортированы, а затем предположить, что это не так.

Как обычно, ваши ответы очень информативны, но все же умудряются быть не настолько информативными, чтобы студенту не оставалось ничего для заполнения.

John Coleman 01.04.2019 15:28

@SimonShine Я пытался решить проблему, предложенную в конце вашего ответа fun find x arr= let val j=length arr fun loop i = if (x== sub(arr,i)) then return i else return loop i-1 in loop j end Это правильно?

user7475343 02.04.2019 11:14

@ maverick98: Комментарии StackOverflow не идеальны для обсуждения частичных решений других проблем, кроме того, о чем был первоначальный вопрос. И нет. :)

sshine 02.04.2019 11:25

Другие вопросы по теме