LISP : проверка уникальности элемента в списке
| Правила | Регистрация | Пользователи | Сообщения за день |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > LISP : проверка уникальности элемента в списке

LISP : проверка уникальности элемента в списке

Ответ
Поиск в этой теме
Непрочитано 15.03.2013, 12:06 #1
LISP : проверка уникальности элемента в списке
WhiteShark
 
Регистрация: 30.03.2012
Сообщений: 101

Задача: определить, уникален ли элемент списка (как вариант - количество вхождений элемента)
Дано: список

Есть ли у кого красивое решение?
Просмотров: 6652
 
Непрочитано 15.03.2013, 12:13
#2
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,411


см. member, assoc, vl-remove, vl-remove-if, vl-remove-if-not и т.п.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 15.03.2013, 12:31
#3
WhiteShark


 
Регистрация: 30.03.2012
Сообщений: 101


Ну список функций то у меня перед глазами ) еще mapcar и apply есть ) но как-то не клеится
если делать последовательный member то проверка будет только для хвоста списка, то есть упускается начало исходного списка
assoc не подходит потому что список просто а не из пар (1 2 3 4 5 2)
vl-remove не подходит потому что удаляет все вхождения не проверяя уникальные ли они
ну а тест-функция для vl-remove-if, vl-remove-if-not есть как раз искомая функция )
WhiteShark вне форума  
 
Непрочитано 15.03.2013, 12:34
1 | #4
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,411


Код:
[Выделить все]
 (setq item 1
      lst  '(1 2 3 4 5 6 "a" "3" "1" 1)
      ) ;_ end of setq

(length (vl-remove-if-not
          (function
            (lambda (x)
              (equal x item)
              ) ;_ end of LAMBDA
            ) ;_ end of function
          lst
          ) ;_ end of vl-remove-if-not
        ) ;_ end of LENGTH
И проверяй длину результата.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 15.03.2013, 12:41
#5
WhiteShark


 
Регистрация: 30.03.2012
Сообщений: 101


Виноват-с, не совсем правильно сформулировал. Проверить надо присутствуют ли в списке уникальные элементы. То есть надо не взять какой то элемент и проверить присутствует ли он в списке, а взять каждый элемент списка и проверить не входит ли он в него всего 1 раз.
Есть идея, конечно, проверять после vl-remove на четность количество оставшихся элементов.. но как то не коряво это кажется
WhiteShark вне форума  
 
Непрочитано 15.03.2013, 13:00
#6
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,411


Разбираться мне некогда, попробуй по аналогии:
Код:
[Выделить все]
 (defun _kpblc-list-dublicates-remove (lst / result)
                                     ;|
*    Функция исключения дубликатов элементов списка 
*    Параметры вызова:
*	lst	обрабатываемый список
*    Возвращаемое значение: список без дубликатов соседних элементов
*    Примеры вызова:
(_kpblc-list-dublicates-remove '((0.0 0.0 0.0) (10.0 0.0 0.0) (10.0 0.0 0.0) (0.0 0.0 0.0)) nil)
((0.0 0.0 0.0) (10.0 0.0 0.0) (0.0 0.0 0.0))
|;
  (foreach x lst
    (if (not (member x result))
      (setq result (cons x result))
      ) ;_ end of if
    ) ;_ end of foreach
  (reverse result)
  ) ;_ end of defun

(defun _kpblc-list-dublicates-stay (lst / res)
                                   ;|
*    Оставляет дубликаты списка
|;
  (if (and lst (= (type lst) 'list))
    (progn
      (foreach item lst
        (if (member item (cdr (member item lst)))
          (setq res (cons item res))
          ) ;_ end of if
        ) ;_ end of foreach
      (setq res (_kpblc-list-dublicates-remove (reverse res)))
      ) ;_ end of progn
    ) ;_ end of if
  res
  ) ;_ end of defun
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 15.03.2013, 13:09
#7
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,839


Цитата:
Сообщение от WhiteShark Посмотреть сообщение
взять каждый элемент списка и проверить не входит ли он в него всего 1 раз.
Код:
[Выделить все]
 (defun unic(lst)
  ((lambda (frec) (frec '() lst))
   (lambda (l1 l2)
     (if l2
         (if (not (member (car l2) l1))
             (frec (cons (car l2) l1) (cdr l2)))
         T))))
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 15.03.2013, 14:23
#8
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,996


Одна из моих старых функций. Предназначалась, в том числе, и для работы с вещественными числами. поэтому используется сравнение до 1e-6
Код:
[Выделить все]
(defun mip_MakeUniqueMembersOfListWithCount  ( lst / OutList head countelt)
;; ===== mip_MakeUniqueMembersOfListWithCount =====
;; Removes the same (duplicate) items from the list
;; Quantifying the number of occurrences of an element
;; Use
;; (Mip_MakeUniqueMembersOfListWithCount '(1 2 3 1 2 3 1 1 2 2))
;; Return ((1. 4) (2. 4) (3. 2))  
;; Удаляет одинаковые (дубликаты) элементы из списка
;; с подсчетом числа вхождений элемента
;;Применение
;;(mip_MakeUniqueMembersOfListWithCount '(1 2 3 1 2 3 1 1 2 2))
;; Вернет ((1 . 4) (2 . 4) (3 . 2))
  
  (while lst
    (setq head (car lst)
	  countelt 0
          lst (vl-remove-if '(lambda(pt)(if (equal pt head 1e-6)(setq countelt (1+ countelt)) nil)) lst)
          OutList (append OutList (list (cons head countelt)))))
  OutList
  )
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Автор темы   Непрочитано 15.03.2013, 14:39
#9
WhiteShark


 
Регистрация: 30.03.2012
Сообщений: 101


Дима_, при всём уважении... как то не работает. На листе '(3 10 3 10 1) возвращает nil
WhiteShark вне форума  
 
Непрочитано 15.03.2013, 14:50
#10
Vov.Ka


 
Регистрация: 21.07.2008
Луцьк
Сообщений: 179


Код:
[Выделить все]
 (vl-remove-if (function (lambda (e) (vl-position e (cdr (member e lst))))) lst)
Vov.Ka вне форума  
 
Непрочитано 15.03.2013, 14:57
#11
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,839


Цитата:
Сообщение от WhiteShark Посмотреть сообщение
взять каждый элемент списка и проверить не входит ли он в него всего 1 раз
...
при всём уважении... как то не работает. На листе '(3 10 3 10 1) возвращает nil
Я сделал то, что написанно Вами - функция проверяет (то есть возращает false либо true - в автолисп терминологии T nil) в зависимости от наличия дублирующих элементов - то есть если спиок "уникальный" - все элементы по 1 разу - вернет T (можете проверить), а Ваш '(3 10 3 10 1) - как бы уже дважды не уникален - и естественно возращает nil.
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Автор темы   Непрочитано 15.03.2013, 15:07
#12
WhiteShark


 
Регистрация: 30.03.2012
Сообщений: 101


Дима_, я же поправился. Нужно чтобы функция возвращала T если хоть один элемент присутствует меньше 2ух раз в списке
То есть если в списке какое то число встречается единожды, то это допустим T, а если там только числа, которые повторяются 2 и более раз, то nil.
Будьте любезны немного подправить. Вам я думаю несложно ) А я в ваш код смотрю и только диву даюсь какие в LISPе формы допустимы )

А в принципе можете и не переделывать.. Вариант от Vov.Ka - то, что надо!
Всем спасибо!

Последний раз редактировалось WhiteShark, 15.03.2013 в 15:25.
WhiteShark вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > LISP : проверка уникальности элемента в списке



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Lisp. Проблема после копирование стиля несущего элемента (ADT) из файла молодой человек LISP 1 02.05.2011 22:56
Lisp. Редактирование элемента во внешней ссылке без команды _refedit молодой человек LISP 8 08.04.2011 23:00
Проверка прочности ж/б элемента Dimitrius Расчетные программы 2 03.07.2007 22:10
Проверка нажатия CTRL в LISP в фоновом режиме(не grread) BH LISP 10 22.08.2006 22:23
lisp : проверка наличия типа линии в файле Кулик Алексей aka kpblc LISP 4 21.06.2005 08:04