Петля не работает должным образом

Так

(let loop ((p (- (length lst) 1)) (i 0) (l lst))
  (cond
    ((= p 0)  
     lst)
    ((= i p)  
     (loop (+ p -1) 0 l))
    ((> (vector-ref (convert lst) i) (vector-ref (convert lst) p)) 
     (loop (+ p 0) (+ i 1) (swap (convert l) i p)))
    ((< (vector-ref (convert lst) i) (vector-ref (convert lst) p)) 
     (loop (+ p 0) (+ i 1) l))) 

он вернет исходное состояние на (= p 0), когда я отправлю lst из '#(3 2 1), но когда я запускаю функцию swap отдельно, он вернет '#(1 2 3). p - это последний массив, а i - первый в массиве.

Значит, в случае, когда элементы равны =, то цикл завершен? Это как минимум кончится. Что делает convert? Если аргумент является вектором, почему имя параметра указывает, что это список?

Sylwester 31.07.2018 03:48

преобразовать только изменения в список в вектор и условие = p 0 завершит процесс

이재찬 31.07.2018 09:39

Ваши конверсии портят ваш результат. lst никогда не изменялся, это то, что вы возвращаете. последний должен использовать else вместо (> ...), поскольку, если он не больше, он равен или меньше. Не нужно это проверять. Я понятия не имею, что это должно делать, но очевидно, почему это не должно работать. Ваши проблемы не имеют ничего общего с именем let.

Sylwester 31.07.2018 13:19

Не могли бы вы привести минимальный полный пример, включая определения как convert, так и swap, а также значение lst? Приведите пример, который можно запустить, не догадываясь. (см. MCVE)

Alex Knauth 31.07.2018 16:45

Спасибо, Алекс, я понял, что постоянно передаю lst вместо l после того, как вы упомянули lst. Думаю, теперь это работает. Swap просто просто поменяйте местами две переменные, которые все, что он делает, и convert просто преобразует список-> вектор

이재찬 31.07.2018 23:53

Если ваша проблема решена, вы должны опубликовать ответ и принять его, чтобы этот вопрос больше не помечался как открытый.

Neowizard 01.08.2018 14:30
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
6
102
2

Ответы 2

Используйте l вместо lst, чтобы возвращалось значение окончательный, а не оригинал.

Вы начинаете с l = lst и продвигаетесь в цикле, меняя l на каждом шаге.

Когда вы достигнете последнего состояния, просто верните то, что вы построили, l.

'#(3 2 1) - это векторное обозначение. (list '#(3 2 1)) на входе должен возвращать (#(1 2 3))

Однако это не самое страшное. Перекрытие между списком и вектором несколько раз в одном и том же случае cond сигнализирует о том, что что-то не так. Вы тратите много времени и памяти, чтобы создать вектор, который используете только один. Я предлагаю преобразовать в вектор на входе и в список на выходе.

И можно было бы сделать несколько улучшений в обозначениях. Обычно функция lisp, которая преобразует типы, обозначается знаком «->» между типами. Итак, convert должен быть (список-> вектор), и у вас должен быть соответствующий (вектор-> список). Одна функция не должна делать и то, и другое, по крайней мере, без явных аргументов, чтобы избежать неправильного типа данных.

Также swap должен быть swap!, поскольку он изменяет структуру данных на месте.

Также есть логическая ошибка. Если два элемента во входном списке равны, вы пропустите все свои предложения cond и вызовете исключение.

(let loop ((p (- (length lst) 1)) (i 0) (vec (list->vector l))
  (cond
    ((= p 0)  
     (vector->list lst))
    ((= i p)  
     (loop (- p 1) 0 l))
    ((> (vector-ref vec i) (vector-ref vec p)) 
     (loop p (+ i 1) (swap! vec i p)))
    (else 
     (loop p (+ i 1) l))) 

Другие вопросы по теме