Форум программистов, компьютерный форум, киберфорум
Lisp
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
18 / 18 / 6
Регистрация: 02.07.2011
Сообщений: 67

Есть ли список внутри списка

23.08.2013, 08:01. Показов 1526. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, уважаемые форумчане!
Укажите, пожалуйста, на ошибку. Функция должна определять, есть ли список внутри списка.

Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(defun has-list-in (lst)
  (if (null lst)
      nil
      (if (listp (car lst))
          lst
          (has-list-in (cdr lst)))))
 
(format t "1: ~A~%" (has-list-in '()))
(format t "2: ~A~%" (has-list-in '(1)))
(format t "3: ~A~%" (has-list-in '('a)))
(format t "4: ~A~%" (has-list-in '(1 2 3 4 5)))
(format t "5: ~A~%" (has-list-in '(1 2 3 'a 4 5)))
(format t "6: ~A~%" (has-list-in '(1 2 3 (4 5) 6)))
 
(format t "'a is list: ~A~%" (listp 'a))
Вывод:
Code
1
2
3
4
5
6
7
1: NIL
2: NIL
3: ('A)
4: NIL
5: ('A 4 5)
6: ((4 5) 6)
'a is list: NIL
Почему у меня символ определяется как список?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
23.08.2013, 08:01
Ответы с готовыми решениями:

Предикат p(U, V, L) - истинный, когда список L есть список из элементов списка U без элементов списка V (Visual Prolog)
Здравствуйте, помогите разобраться с моей реализацией Видел уже решение данной задачи другим способом, но очень интересно понять почему...

Есть список. Есть цикл. Как в цикле указать последний элемент списка?
Пример: ArrayList<String> str = new ArrayList<>(); BufferedReader read = new BufferedReader(new InputStreamReader(System.in));...

Определить, есть ли повторения значений параметров внутри списка
ЗАДАЧА: Создать список List значений некоторого параметра путем компоновки данных из базы данных, которую задать в следующем виде: параметр...

15
4528 / 3522 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
23.08.2013, 10:11
У вас одна кавычка лишняя. Кавычка перед внешними скобками закавычила всё, поэтому внутри достаточно написать '(1 2 3 a 4 5). А в вашем случае он 'a преобразовал в (quote a) и, естественно, не стал вычислять - вот и список.

Добавлено через 43 секунды
Можете проверить:
Code
1
2
CL-USER> (equal '(1 'a) '(1 (quote a)))
T
1
18 / 18 / 6
Регистрация: 02.07.2011
Сообщений: 67
23.08.2013, 10:40  [ТС]
Спасибо, всё понятно! То есть кавычка - это макрос, который перед выполнением всегда преобразуется в (quote ...)?
В последнем случае (listp (quote a)) кавычка естесственно вычислилась, а в остальных случаях (quote (quote a)) вернуло список из 2-х элементов.
0
4528 / 3522 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
23.08.2013, 10:50
Да, совершенно точно.
0
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38190 / 21125 / 4307
Регистрация: 12.02.2012
Сообщений: 34,732
Записей в блоге: 14
23.08.2013, 11:06
Задачу можно решить и вот так:

Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
;; HomeLisp
(defun has-list (lst)
  (apply 'or (mapcar #'listp lst)))
 
==> has-list
 
(has-list '(1 2 3))
 
==> NIL
 
(has-list '(1 (2 3)))
 
==> T
В Common Lisp это решение работать не будет, т.к. в CL or - макро. Но можно поступить так:

Lisp
1
2
3
4
5
6
7
8
(defmacro has-list (lst)
 (let ((lp (mapcar #'listp lst)))
   `(or ,@lp)))
HAS-LIST
CL-USER 11 : 2 > (has-list (1 (2 3)))
T
CL-USER 12 : 2 > (has-list (1 2 3))
NIL
Поскольку в CL используется макро, то его аргумент не квотируется.
1
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4575 / 2774 / 491
Регистрация: 28.04.2012
Сообщений: 8,779
23.08.2013, 12:08
Лучший ответ Сообщение было отмечено как решение

Решение

Цитата Сообщение от Catstail Посмотреть сообщение
В Common Lisp это решение работать не будет, т.к. в CL or - макро. Но можно поступить так:
А нужно так:
Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
(defun has-lists-p (list)
  (find-if #'listp list))
 
(defparameter *test-lists*
  '(()
    (1)
    ('a)
    (1 2 3 4 5)
    (1 2 3 'a 4 5)
    (1 2 3 (4 5) 6)))
 
(loop :for list :in *test-lists*
      :for i :upfrom 1
      :do (format t "~D: ~A~%" i (has-lists-p list)))
 
; 1: NIL
; 2: NIL
; 3: (QUOTE A)
; 4: NIL
; 5: (QUOTE A)
; 6: (4 5)
=)
4
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38190 / 21125 / 4307
Регистрация: 12.02.2012
Сообщений: 34,732
Записей в блоге: 14
23.08.2013, 12:27
Цитата Сообщение от korvin_ Посмотреть сообщение
А нужно так:
- почему такая модальность? Хотя, конечно, с find-if рациональнее...
0
 Аватар для _sg
4710 / 4405 / 380
Регистрация: 12.05.2012
Сообщений: 3,102
23.08.2013, 14:19
Цитата Сообщение от andreysv Посмотреть сообщение
Функция должна определять, есть ли список внутри списка.
Lisp
1
2
3
4
(defun insider (w) (some #'listp w))
 
> (insider '(1 2 3 (4 5) 6))
T
Добавлено через 3 минуты
Lisp
1
2
3
4
5
6
7
(defun insider (w)
  (cond ((null w) nil)
        ((atom (car w)) (insider (cdr w)))
        (t t)))
 
> (insider '(1 2 3 (4 5) 6))
T
Добавлено через 1 минуту
Lisp
1
2
3
4
5
(defun insider (w)
  (when w (if (atom (car w)) (insider (cdr w)) t)))
 
> (insider '(1 2 3 (4 5) 6))
T
Добавлено через 3 минуты
Lisp
1
2
3
4
5
(defun insider (w)
  (when w (or (listp (car w)) (insider (cdr w)))))
 
> (insider '(1 2 3 (4 5) 6))
T
2
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4575 / 2774 / 491
Регистрация: 28.04.2012
Сообщений: 8,779
23.08.2013, 14:30
Цитата Сообщение от Catstail Посмотреть сообщение
почему такая модальность?
Lisp
1
(has-list xs)
Добавлено через 5 минут
С find есть только одна особенность: как воспринимать nil-результат:
Lisp
1
2
(find-if #'listp '(1 2 3 () 4))
; NIL
2
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38190 / 21125 / 4307
Регистрация: 12.02.2012
Сообщений: 34,732
Записей в блоге: 14
23.08.2013, 15:16
Есть еще функция forsome, с помощью которой решение получается совсем тривиальным:

Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
(defun has-list (lst) 
  (forsome lst #'listp))
 
==> has-list
 
(has-list '(1 2 3))
 
==> NIL
 
(has-list '(1 2 (a b) 3))
 
==> T
 
(has-list '(1 2 nil 3))
 
==> T
Добавлено через 1 минуту
Цитата Сообщение от korvin_ Посмотреть сообщение
(has-list xs)
- да, с переменной на этом месте будут проблемы... Можно, конечно, макрос доработать, но возрастет сложность.
1
 Аватар для nullxdth
2304 / 1063 / 77
Регистрация: 12.03.2013
Сообщений: 4,987
23.08.2013, 15:50
Лучший ответ Сообщение было отмечено как решение

Решение

На самом же деле, следует так поступить с CL:
Lisp
1
(some #'listp list) ; если nil считать за список
и
Lisp
1
(some #'consp list) ; если - нет
Добавлено через 1 минуту
Цитата Сообщение от Catstail Посмотреть сообщение
Можно, конечно, макрос доработать, но возрастет сложность.
Макрос тут, конечно же, совершенно не нужен.
3
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4575 / 2774 / 491
Регистрация: 28.04.2012
Сообщений: 8,779
23.08.2013, 20:05
Цитата Сообщение от nullxdth Посмотреть сообщение
На самом же деле, следует так поступить с CL:
Есть одно но: some возвращает T или NIL, в то время как find* возвращает найденный подсписок, как в исходном примере, что позволяет сделать с ним какие-то манипуляции.
1
4528 / 3522 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
23.08.2013, 20:40
Если nil очень смущает, а дополнительная информация не помешает, можно использовать member-if.
2
 Аватар для nullxdth
2304 / 1063 / 77
Регистрация: 12.03.2013
Сообщений: 4,987
24.08.2013, 00:57
Цитата Сообщение от korvin_ Посмотреть сообщение
Есть одно но: some возвращает T или NIL, в то время как find* возвращает найденный подсписок, как в исходном примере, что позволяет сделать с ним какие-то манипуляции.
Да ну. some в самый раз по условию.
И, как ты верно заметил, если искать find'ом с listp, то совершенно не понятно, что означает nil на выходе.
Цитата Сообщение от helter Посмотреть сообщение
Если nil очень смущает, а дополнительная информация не помешает, можно использовать member-if.
А вот c member* таких проблем не будет, как с find'ом, да.
0
18 / 18 / 6
Регистрация: 02.07.2011
Сообщений: 67
24.08.2013, 08:39  [ТС]
Спасибо! Много нового кроме решения самой проблемы.
И как я понял, some – аналог forsome в Common Lisp.
0
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38190 / 21125 / 4307
Регистрация: 12.02.2012
Сообщений: 34,732
Записей в блоге: 14
24.08.2013, 09:54
Решение, которое я предложил в самом начале, не подходит для CL, поскольку макро (чем является OR в CL) нельзя употреблять аргументом Apply. Но вполне допустимо вот такое решение:

Lisp
1
2
(defun h-l (lst)
 (/= 0 (apply '+ (mapcar #'(lambda (x) (if (listp x) 1 0)) lst))))
Что же до макро, то он, разумеется, здесь совершенно не нужен (макро придуманы не для таких ситуаций), но это не значит, что макро не может быть применен. Например, так:

Lisp
1
2
3
4
5
6
(defmacro has-list (lst)
 (cond ((atom lst)   
        `(let ((p ,lst))
          (/= 0 (apply '+ (mapcar #'(lambda (x) (if (listp x) 1 0)) p)))))
       (t (let ((p (mapcar #'listp lst)))
            `(or ,@p)))))
Он корректно обрабатывает вызовы с явным указанием списка и вызовы с переменной:

Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
CL-USER 14 : 2 > (has-list (1 2 3))
NIL
 
CL-USER 15 : 2 > (has-list (1 2 (4) 3))
T
 
CL-USER 16 : 2 > z1
(1 2 3)
 
CL-USER 17 : 2 > z2
(1 2 (3 4) 5 6)
 
CL-USER 18 : 2 > (has-list z1)
NIL
 
CL-USER 19 : 2 > (has-list z2)
T
 
CL-USER 20 : 2 >
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
24.08.2013, 09:54
Помогаю со студенческими работами здесь

У меня есть файл и внутри этого файла есть код, я хочу его открыть в IDLE питон так, чтобы внутри код вывести
У меня есть файл и внутри этого файла есть код, я хочу его открыть в IDLE питоне так, чтобы код можно было выполнить в idle: Файл с таким...

Как исправить форматирование списка? Есть список (экспорт из программы) вида?
Доброго времени суток! Подскажите, пожалуйста: Как исправить форматирование списка? Есть список (экспорт из программы) вида: Общий...

В списке Р заменить первое вхождение списка Р1 (если такое есть) на список Р2
Написать программу с функциями, которая: а)в списке Р заменяет первое вхождение списка Р1( если такое есть) на список Р2; б)строит...

ListIterator добавление элемента в список на нужную позицию и вывод списка через for (ListIterator внутри for)
Доброго дня, нужна помощь с выводом списка через цикл for, внутри которого с помощью ListIterator во время вывода третьего элемента на...

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


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

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[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-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru