Форум программистов, компьютерный форум, киберфорум
Lisp
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.56/9: Рейтинг темы: голосов - 9, средняя оценка - 4.56
3 / 3 / 3
Регистрация: 17.10.2012
Сообщений: 147

Написать функцию со списками

19.10.2015, 18:39. Показов 2018. Ответов 24
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет всем!

Нахлынула недавно задача:
Напишите функцию (range S М N P), которая выдает список элементов списка S, удовлетворяющих некоторому предикату P и расположенных между М-ным и N-ным элементами включительно.
Вообще не понимаю, что надо сделать. Это как-то связано в дискретной математикой? Предикаты ...
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
19.10.2015, 18:39
Ответы с готовыми решениями:

Описать функцию, работающую с двумя списками
Доброго времени суток, помогите пожалуйста с заданием: Опишите функцию, которая определяет, является ли первое множество подмножеством...

Написать программу со списками
Написать программу для сортировки списка методом селекции: из списка выбирается максимальный элемент и переносится в голову результирующего...

Написать программу со списками и текстовыми файлами
Задача (алфавитно-частотный словарь). В файле записан текст. Нужно записать в другой файл в столбик все слова, встречающиеся в тексте, в...

24
4528 / 3522 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
19.10.2015, 18:51
Предикат — это функция, возвращающая логическое значение. С дискретной математикой связано постольку-поскольку. Со здравым смыслом связано. Начинаете цикл по элементам списка и одновременно меняете счётчик. Как только счётчик дошёл до номера М, начинаете подставлять элементы в предикат, и если он возвращает истину, добавляем элемент к результату. Как только счётчик дошёл до N, цикл заканчивается.

В лиспе отбросить первые элементы списка вы можете с помощью функции nthcdr. Самый простой способ добавлять к результату — завести список result и добавлять элементы ему в голову: (push e result); в конце — развернуть (nreverse result).

А вообще, такая функция уже написана, remove-if-not называется.
1
3 / 3 / 3
Регистрация: 17.10.2012
Сообщений: 147
19.10.2015, 20:08  [ТС]
Мне преподаватель пытался объяснить это. Говорил что-то вроде "Сделайте проверку на четность числа". Только причем здесь проверка. Можете помочь реализовать этот код на лиспе, не прибегая к использованию лямбды?
0
4528 / 3522 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
19.10.2015, 20:10
Наверно, это он предлагал в качестве предиката взять проверку на чётность. То есть собрать все чётные числа с такого-то по такое-то. Вроде бы совершенно понятное задание.

Цитата Сообщение от Andrea13 Посмотреть сообщение
Можете помочь реализовать этот код на лиспе, не прибегая к использованию лямбды?
Может быть, я могу помочь, но я не буду вам его писать. Задавайте вопросы. Странная претензия к лямбде, но, вроде она не нужна здесь.
2
 Аватар для castorsky
1978 / 1082 / 87
Регистрация: 29.11.2013
Сообщений: 3,353
19.10.2015, 22:01
Цитата Сообщение от helter Посмотреть сообщение
Странная претензия к лямбде, но, вроде она не нужна здесь.
как предикат, хотя можно и написать отдельно
0
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38187 / 21122 / 4307
Регистрация: 12.02.2012
Сообщений: 34,729
Записей в блоге: 14
19.10.2015, 22:27
Lisp
1
2
3
4
5
6
7
8
9
10
11
12
(defun task (lst m n p)
  (remove-if-not p (subseq lst m (+ n 1))))
 
==> task
 
(task '(1 2 3 4 11 22 33 44 55) 3 6 #'oddp)
 
==> (11 33)
 
(task '(1 2 3 4 11 22 33 44 55) 3 6 #'evenp)
 
==> (4 22)
3
4528 / 3522 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
19.10.2015, 22:33
Цитата Сообщение от castorsky Посмотреть сообщение
как предикат, хотя можно и написать отдельно
Внутри функции лямбды не нужны, предикат же аргументом идёт.

Цитата Сообщение от Catstail Посмотреть сообщение
(remove-if-not p (subseq
remove-if-not принимает аргументы :start и :end.
1
3 / 3 / 3
Регистрация: 17.10.2012
Сообщений: 147
19.10.2015, 22:36  [ТС]
Можно ли написать код, но без remove-if-not? Преподаватель скажет, мол "этот remove-if-not упрощает все на свете, сделай все сам, ручками". Как вы думаете?
0
 Аватар для castorsky
1978 / 1082 / 87
Регистрация: 29.11.2013
Сообщений: 3,353
19.10.2015, 22:53
Цитата Сообщение от Andrea13 Посмотреть сообщение
Можно ли написать код, но без remove-if-not?
напишите функцию my-remove-if-not, это не сложно.

Добавлено через 7 минут
Lisp
1
2
3
4
5
6
7
8
;; racket-lang.org
(define (foo S M N P)
  (let ((v (list->vector S)))
    (for/list ((i (range M (add1 N)))
               #:when (P (vector-ref v i)))
      (vector-ref v i))))
 
(foo '(1 2 3 4 5 6 7 8 9) 2 6 odd?)
2
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38187 / 21122 / 4307
Регистрация: 12.02.2012
Сообщений: 34,729
Записей в блоге: 14
20.10.2015, 11:00
Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(defun task (lst m n p &optional (c 0))
  (cond ((> c n) nil)
        ((< c m) (task (cdr lst) m n p (+ c 1)))
        (t (if (funcall p (car lst)) (cons (car lst) (task (cdr lst) m n p (+ c 1)))
                                     (task (cdr lst) m n p (+ c 1))))))
 
==> task
 
(task '(1 2 3 11 22 33 44 66 88) 4 7 #'oddp)
 
==> (33)
 
(task '(1 2 3 11 22 33 44 66 88) 4 7 #'evenp)
 
==> (22 44 66)
3
3 / 3 / 3
Регистрация: 17.10.2012
Сообщений: 147
27.10.2015, 19:28  [ТС]
Преподаватель мне дал пример, по которому стало все понятно.
Функция должна работать так:
Lisp
1
2
3
4
5
(func '((1 2 8 15 18 22 50 53 57 98 104) 8 98 func2)
где func2 - функция, которая проверяет четность числа (если число четное, то заносит его в список)
В func2 можно использовать лямбда-выражение, а можно и не использовать. Не знаю, как проще.
 
==> (8 18 22 50 98)
Добавлено через 22 минуты
Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(defun task (lst m n p &optional (c 0))
  (cond ((> c n) nil)
        ((< c m) (task (cdr lst) m n p (+ c 1)))
        (t (if (funcall p (car lst)) (cons (car lst) (task (cdr lst) m n p (+ c 1)))
                                     (task (cdr lst) m n p (+ c 1))))))
 
==> task
 
(task '(1 2 3 11 22 33 44 66 88) 4 7 #'oddp)
 
==> (33)
 
(task '(1 2 3 11 22 33 44 66 88) 4 7 #'evenp)
 
==> (22 44 66)
Не знаю почему, но он не работает, если ввести что-то вроде:
Lisp
1
(task '(1 2 3 4 5 6 7 12 33 45 57) 12 57 'oddp)
Добавлено через 4 минуты
Я ожидал от него:
(33 45 57)
0
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38187 / 21122 / 4307
Регистрация: 12.02.2012
Сообщений: 34,729
Записей в блоге: 14
27.10.2015, 19:38
Да, есть ошибка. Вот:

Lisp
1
2
3
4
5
(defun task (lst m n p &optional (c 0))
  (cond ((or (> c n) (null lst)) nil)
        ((< c m) (task (cdr lst) m n p (+ c 1)))
        (t (if (funcall p (car lst)) (cons (car lst) (task (cdr lst) m n p (+ c 1)))
                                     (task (cdr lst) m n p (+ c 1))))))
Имей в виду, что n и m - это номера элементов списка. Поэтому задавать 57 здесь не вполне корректно.
2
3 / 3 / 3
Регистрация: 17.10.2012
Сообщений: 147
27.10.2015, 20:13  [ТС]
Хм, а нельзя сделать так, чтобы n и m были не номерами элементов списка, а самими значениями?
Например, я хочу сделать так:

Lisp
1
(task '(33 44 55 66 77 88 99 111 222) 33 111 'oddp) --> (33 55 77 99 111)
Типа я задаю диапазон из списка.
Да и в самом коде мы никогда не пользовались подобным: "&optional" или "(c 0)" - я даже не знаю, что это и зачем.
0
 Аватар для _sg
4710 / 4405 / 380
Регистрация: 12.05.2012
Сообщений: 3,102
27.10.2015, 20:38
Лучший ответ Сообщение было отмечено Andrea13 как решение

Решение

Andrea13, это будет другая задача, по правилам форума одна тема - одна задача, как вариант:
Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(defun conditional-range (w n m p &aux (a (car w)) (d (cdr w)))
  (cond ((null w) nil)
        ((zerop m) (when (funcall p a) (list a)))
        ((and (<= n 0) (funcall p a))
         (cons a (conditional-range d 0 (1- m) p)))
        ((conditional-range d (1- n) (1- m) p))))
 
> (conditional-range '(1 2 3 4 5 6 7 12 33 45 57) 12 57 'oddp)
NIL
> (conditional-range '(1 2 3 11 22 33 44 66 88) 4 7 #'evenp)
(22 44 66)
> (conditional-range '(1 2 3 11 22 33 44 66 88) 4 7 #'oddp)
(33)
> (conditional-range '() 12 57 'oddp)
NIL
Добавлено через 25 секунд
Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Решение 20.1.2
 
(defun conditional-range (w n m p)
  (loop for a in w for b from 0
        when (> b m) return v
        when (and (>= b n) (funcall p a))
        collect a into v))
 
> (conditional-range '(1 2 3 4 5 6 7 12 33 45 57) 12 57 'oddp)
NIL
> (conditional-range '(1 2 3 11 22 33 44 66 88) 4 7 #'evenp)
(22 44 66)
> (conditional-range '(1 2 3 11 22 33 44 66 88) 4 7 #'oddp)
(33)
> (conditional-range '() 12 57 'oddp)
NIL
Добавлено через 2 минуты
Цитата Сообщение от Andrea13 Посмотреть сообщение
а нельзя сделать так, чтобы n и m были не номерами элементов списка, а самими значениями?
таких значений может быть только одно, несколько или не быть совсем.

Добавлено через 3 минуты
вариант без спецификатора &aux:
Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(defun conditional-range (w n m p)
  (cond ((null w) nil)
        ((zerop m) (when (funcall p (car w)) (list (car w))))
        ((and (<= n 0) (funcall p (car w)))
         (cons (car w) (conditional-range (cdr w) 0 (1- m) p)))
        ((conditional-range (cdr w) (1- n) (1- m) p))))
 
> (conditional-range '(1 2 3 4 5 6 7 12 33 45 57) 12 57 'oddp)
NIL
> (conditional-range '(1 2 3 11 22 33 44 66 88) 4 7 #'evenp)
(22 44 66)
> (conditional-range '(1 2 3 11 22 33 44 66 88) 4 7 #'oddp)
(33)
> (conditional-range '() 12 57 'oddp)
NIL
2
3 / 3 / 3
Регистрация: 17.10.2012
Сообщений: 147
27.10.2015, 20:41  [ТС]
Я просто стал отталкиваться от примера:

Lisp
1
(task '(33 44 55 66 77 88 99 111 222) 33 111 'oddp) --> (33 55 77 99 111)
Где после списка указываются не номера каждого элемента, а сама граница, которая есть в списке.
Можно, конечно, попробовать разобрать и ваши варианты, но в них есть неизученный материал.
0
 Аватар для _sg
4710 / 4405 / 380
Регистрация: 12.05.2012
Сообщений: 3,102
27.10.2015, 20:47
Andrea13, пример противоречит условию задачи:
Цитата Сообщение от Andrea13 Посмотреть сообщение
расположенных между М-ным и N-ным элементами включительно
0
3 / 3 / 3
Регистрация: 17.10.2012
Сообщений: 147
02.11.2015, 18:35  [ТС]
На всякий случай продублирую.
Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(defun conditional-range (w n m p)
  (cond ((null w) nil)
        ((zerop m) (when (funcall p (car w)) (list (car w))))
        ((and (<= n 0) (funcall p (car w)))
         (cons (car w) (conditional-range (cdr w) 0 (1- m) p)))
        ((conditional-range (cdr w) (1- n) (1- m) p))))
 
> (conditional-range '(1 2 3 4 5 6 7 12 33 45 57) 12 57 'oddp)
NIL
> (conditional-range '(1 2 3 11 22 33 44 66 88) 4 7 #'evenp)
(22 44 66)
> (conditional-range '(1 2 3 11 22 33 44 66 88) 4 7 #'oddp)
(33)
> (conditional-range '() 12 57 'oddp)
NIL
Мне преподаватель сказал сделать подсчет не с нуля, а с единицы, например в вашем случае:
(conditional-range(1 2 3 44 55 66 77 88 100 6756) 1 3 'oddp)
Подсчет начнется с 0, 1, 2, 3, 4, 5 .... n
А надо, чтобы первый элемент списка имел индекс 1, а не 0.
Чтобы с единицы начинался подсчет, например, в вашем случае он выдаст:
Lisp
1
(1 2 3 44 55 66 77 88 100 6756) 2 6 'oddp) --> (3 55 77)
А нужно:
Lisp
1
(1 2 3 44 55 66 77 88 100 6756) 2 6 'oddp) --> (3 55)
Он также сказал, что не выполняется вот это место:

Lisp
1
 ((and (<= n 0) (funcall p (car w)))
Мол n не должен быть меньше нуля. n должен равен единице (первый элемент).
0
 Аватар для _sg
4710 / 4405 / 380
Регистрация: 12.05.2012
Сообщений: 3,102
02.11.2015, 20:38
Lisp
1
2
3
4
5
6
7
8
9
(defun conditional-range (w n m p)
  (cond ((null w) nil)
        ((= m 1) (when (funcall p (car w)) (list (car w))))
        ((and (<= n 1) (funcall p (car w)))
         (cons (car w) (conditional-range (cdr w) 0 (1- m) p)))
        ((conditional-range (cdr w) (1- n) (1- m) p))))
 
> (conditional-range '(1 2 3 44 55 66 77 88 100 6756) 2 6 'oddp)
(3 55)
1
3 / 3 / 3
Регистрация: 17.10.2012
Сообщений: 147
03.11.2015, 11:35  [ТС]
(f '(1 2 3 44 55 66 345 654 1000 1004 5432) 3 8 'evenp) --> (44 66 654)
(f '(1 2 3 44 55 66 345 654 1000 1004 5432) 3 8 'oddp) --> (3 55 345)

Как заставить программу вывести те же значения, если просто поменяли границы?
То есть, как препод сказал - это 0 разницы. Он должен выводить тоже самое.
(f '(1 2 3 44 55 66 345 654 1000 1004 5432) 8 3 'oddp) --> (3 55 345)
0
 Аватар для _sg
4710 / 4405 / 380
Регистрация: 12.05.2012
Сообщений: 3,102
03.11.2015, 11:51
Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
(defun conditional-range (w n m p)
  (cond ((null w) nil)
        ((= m 1) (when (funcall p (car w)) (list (car w))))
        ((and (<= n 1) (funcall p (car w)))
         (cons (car w) (conditional-range (cdr w) 0 (1- m) p)))
        ((conditional-range (cdr w) (1- n) (1- m) p))))
 
(defun over-conditional-range (w n m p)
  (if (<= n m) (conditional-range w n m p) (conditional-range w m n p)))
 
> (over-conditional-range '(1 2 3 44 55 66 345 654 1000 1004 5432) 3 8 'oddp)
(3 55 345)
> (over-conditional-range '(1 2 3 44 55 66 345 654 1000 1004 5432) 8 3 'oddp)
(3 55 345)
> (over-conditional-range '(1 2 3 44 55 66 345 654 1000 1004 5432) 4 4 'oddp)
NIL
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
03.11.2015, 11:51
Помогаю со студенческими работами здесь

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

Написать шаблонный класс List для работы с одноправленными списками в динамической памяти
Для объектов класса List определить операции проверки списка на пустоту, добавления элемента в начало списка, в конец списка, подсчет...

List (Написать программу для работы со списком и реализовать следующие операции над списками)
Написать программу для работы со списком и реализовать следующие операции над списками: 1) перенести в начало списка его последний...

Написать функцию. которая аргументом принимает тип происшествия и возвращает функцию
Написать функцию. которая аргументом принимает тип происшествия и возвращает функцию, которая принимает улицу и возвращает сообщение...

Написать функцию, которая, в зависимости от выбора пользователя вызывает соответствующую функцию
Помогите, что то я не могу понять задачи, даже не знаю с чего начать)))) 5. Написать функцию, которая, в зависимости от выбора...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это дополнительная запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru