#scheme
#схема
Вопрос:
Проблема
Подсчитайте количество вхождений в список, они должны быть смежными. Пример: (a a b b c c a e)
, возвращает ( (a 2) (b 2) (c 2) (a 1) (e 1) )
.
Я пытался,
(define (loop lst)
(let ((i 1) (j 0))
(do ()
[(> j (- (length lst) 2))]
(if (eq? (car lst) (cadr lst))
(set! i ( i 1))
(display i)
)
(
(set! lst (cdr lst))
(set! j ( j 1))
)
)
)
)
При запуске DrScheme пожаловался
procedure application: expected procedure, given: #<void>; arguments were: #<void>
Как я могу использовать несколько операторов внутри if
или do
цикла, подобного этому?
Спасибо,
Комментарии:
1. -1 Мои глаза! Очки ничего не делают!
2. @Chris Jester-Young: Я не понимаю?
3. Что вы пытаетесь сделать? Это не похоже ни на один код, который захотел бы написать здравомыслящий программист.
4. @Chris Jester-Young: Прости меня! Сейчас я очень стараюсь изучить Scheme. Я был так одержим традиционной структурой императивного языка. Мне было крайне неудобно использовать круглые скобки в качестве блока кода. Честно говоря, я почти сдался!
5. Верно, и именно поэтому я только что отправил вам ответ, основанный на
fold
. Как только вы освоитесь сfold
,map
и т.д., вам больше не захочется использовать циклы в императивном стиле. 🙂 (Кстати, я только что отозвал свой отзыв. Спасибо за объяснение вашей задачи.)
Ответ №1:
О, вы хотите вычислить длину пробега! Угадай что! Еще одна проблема для fold
! 😛
(define (run-lengths lst)
(fold-right (lambda (elem result)
(if (and (pair? result)
(equal? elem (caar result)))
(cons (cons elem ( (cdar result) 1)) (cdr result))
(cons (cons elem 1) result)))
'() lst))
(Моя версия возвращает длины выполнения в виде пар с точками, а не списков длины 2.) Поскольку вы используете Racket, вы можете использовать foldr
вместо fold-right
; таким образом, вам не нужно будет загружать SRFI 1.
Комментарии:
1. @Крис Джестер-Янг: Теперь ты режешь мне глаза. Спасибо!
2. @Чан: Хахаха. Сделайте все возможное, чтобы изучить, как работает моя функция, прочитав о том, как
foldr
это работает. Это просветит вас! 🙂3. @Крис Джестер-Янг: Ну, я знаком со значением слова «сгиб». Я читал из wiki, это похоже на
std::accumulate
в C . Тем не менее,()
это было супер раздражающе : (!4. @Chan: Это в точности как
std::accumulate
. 🙂 Однажды вы привыкнете смотреть на скобки (или, скорее, не смотреть на них). 🙂5. @Chan: Обратите внимание также на разницу в структуре кода. Разработчики Lisp не помещают «висячие» скобки в строку так же, как программисты на языке C * обычно помещают фигурные скобки в строку. Это на самом деле увеличивает читаемость вашего кода. Для получения дополнительной информации ознакомьтесь с этим руководством по стилю lisp: mumble.net /~campbell/scheme/style.txt