Я супер новичок в 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++;
}
}
@JohnColeman Я исправил операторы else, но все же ошибки появляются немного по-другому.
Ваши case
не имеют смысла (где =>
?). В более общем смысле вы, кажется, пытаетесь написать Java-подобный код на SML. Вы думаете слишком императивно, а не функционально. Кроме того, почему вы используете local
, а не let
?
@JohnColeman Спасибо, какие улучшения я должен был внести в этот код, чтобы работать в ML
Совершенно непонятно, что вы пытаетесь сделать. Какой тип функции вы пытаетесь написать? Код очень многословен для 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
, а не логический.
@JohnColeman Пожалуйста, смотрите правку
"Я пытаюсь написать этот код на sml. Он написан на c++" --- почему? Просто напишите код SML в SML. Вы пытаетесь написать императивный код на функциональном языке. Забудьте о C++. Здесь это не очень актуально. Кроме того, вы никогда четко не объясняли, что именно вы пытаетесь сделать. Что такое тип функции, которую вы пытаетесь написать?
@JohnColeman Я пытаюсь написать функцию, которая находит длину наименьшего подмассива, содержащего все элементы большого массива. Пример: 1 2 2 3 2 2 2 3 1 Ответ: 3
Вы уверены, что имеете в виду массив, а не список? Кроме того, когда я просил тип, я искал что-то вроде int list -> int
@JohnColeman Это может быть и то, и другое. Числа задаются как входные данные из файла.
Давайте продолжить обсуждение в чате.
Как говорит Джон Коулман, 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
отсортированы, а затем предположить, что это не так.
Как обычно, ваши ответы очень информативны, но все же умудряются быть не настолько информативными, чтобы студенту не оставалось ничего для заполнения.
@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
Это правильно?
@ maverick98: Комментарии StackOverflow не идеальны для обсуждения частичных решений других проблем, кроме того, о чем был первоначальный вопрос. И нет. :)
Сообщения об ошибках SML/NJ могут быть непрозрачными. Обратите внимание, что вам не хватает подходящего
else
, который не является обязательным в sml.