Фильтровать элементы в списке по длине - Ocaml - PullRequest
5 голосов
/ 29 ноября 2010

У меня есть следующий список:

["A";"AA";"ABC";"BCD";"B";"C"]

Я случайным образом извлекаю элемент из списка.Но элемент, который я извлекаю, должен иметь размер 3, только не меньше 3.

Я пытаюсь сделать это следующим образом:

let randomnum = (Random.int(List.length (list)));;
let rec code c =
    if (String.length c) = 3 then c
    else (code ((List.nth (list) (randomnum)))) ;;
print_string (code ( (List.nth (list) (randomnum)))) ;;

Это прекрасно работает, если случайным образом строка длиной 3выбран из списка.

Но программа не завершает работу, если выбрана строка длиной <3.Я пытаюсь сделать рекурсивный вызов, чтобы новый код продолжал собираться до тех пор, пока мы не получим один из кодов длины = 3. </p>

Я не могу понять, почему это не заканчивается.Ничего не выводится оператором print.

Ответы [ 3 ]

4 голосов
/ 18 февраля 2012

Что вы, вероятно, хотите написать, это

 let rec code list =
   let n = Random.int (List.length list) in
   let s = List.nth list in
   if String.length s < 3 then code list else s

Обратите внимание, что в зависимости от размера списка и количества строк размером более 3 может потребоваться работать непосредственно со списком, в котором только строки больше 3:

let code list =
  let list = List.filter (fun s -> String.length s >= 3) list in
  match list with
  | [] -> raise Not_found
  | _  -> List.nth list (Random.int (List.length list)) 

Эта вторая функция лучше, так как она всегда завершается, особенно когда нет строк больше 3.

3 голосов
/ 29 ноября 2010

Вы выбираете случайное число только один раз. Допустим, вы выбрали 5. Вы просто продолжаете повторять с 5 раз за разом. Вам нужно получить новое случайное число.

1 голос
/ 23 февраля 2012

Для завершения вашего кода было бы лучше сначала отфильтровать список подходящих элементов, а затем взять ваше случайное число:

let code list =
   let suitables = List.filter (fun x -> String.length x = 3) list in
   match List.length suitables with
   | 0 -> raise Not_found (* no suitable elements at all! *)
   | len -> List.nth suitables (Random.int len)

В противном случае ваш код займет очень долгозавершить большой список элементов размером <> 3;или, что еще хуже, в списке без элемента размера 3 он не будет завершен вообще!

...