Может кто-нибудь сказать мне, что я делаю не так?
С (for ([x (- (length losl) 1)]) ;...
l oop не повторяется до конца ввода список. С заданным значением (length losl)
равно 3; поэтому предложение l oop эквивалентно (for ([x 2]) ;...
, что аналогично (for ([x (in-range 2)]) ;...
. Это генерирует значения 0 и 1 для x
, но 2 никогда не достигается, поэтому последний список никогда не проверяется. Чтобы исправить эту проблему, измените на:
(define (longestSub losl)
(set! longest (car losl))
(for ([x (length losl)])
(if (>= (length (list-ref losl x)) (length longest))
(set! longest (list-ref losl x))
(void losl)))
(display longest))
Кстати, вы можете избавиться от (void losl)
, используя when
вместо if
:
(define (longestSub losl)
(set! longest (car losl))
(for ([x (length losl)])
(when (>= (length (list-ref losl x)) (length longest))
(set! longest (list-ref losl x))))
(display longest))
Используя все oop и set!
для этого, возможно, не самое идиоматическое c решение. Другой подход заключается в использовании рекурсии и вспомогательной функции, которая передает текущий самый длинный подсписок:
(define (longest-sublist losl)
(define (lsl-helper losl longest)
(cond [(empty? losl)
longest]
[(>= (length (first losl)) (length longest))
(lsl-helper (rest losl) (first losl))]
[else (lsl-helper (rest losl) longest)]))
(lsl-helper losl '()))
Оба решения будут работать, но есть пара отличий. Решение OP потерпит неудачу с ошибкой времени выполнения в случае пустого списка для ввода: (longestSub '())
. Но это рекурсивное решение будет возвращать пустой список для того же ввода вместо сбоя. Какое поведение предпочтительнее, зависит от ОП. Другое отличие состоит в том, что это рекурсивное решение возвращает самый длинный подсписок, а OP-решение просто печатает его.