2010-11-29 1 views
5

У меня есть следующий список:Фильтрующие элементы в списке по длине - OCaml

["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.

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

ответ

3

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

+0

спасибо. я просто попробовал это и собирался удалить этот пост и увидел ваш ответ :) Еще раз спасибо. – JJunior 2010-11-29 05:18:50

4

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

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.

1

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

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, он вообще не завершится!