Форум программистов, компьютерный форум, киберфорум
Наши страницы
Lisp
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
Argentum21
1 / 1 / 1
Регистрация: 05.03.2014
Сообщений: 75
1

Mapcar для sin

25.06.2014, 17:37. Просмотров 779. Ответов 11
Метки нет (Все метки)

Здравствуйте. Передо мной стоит следующая задача:
Написать программу ввода списка имен функций, ввода списка данных и получения списка результатов, используя функцию mapcar. Имена функций и данные вводить из файла. Функции следующие: max, -, apply, abs.

Список имен функций (файл .txt): (max - apply abs)
Список данных: (файл .txt): ( ((4) (7) (5)) ((4 2) (2 1)) ((sin) ( (1) )) (-100) )

Вопрос таков: Как сделать так, чтобы можно было посчитать значения синуса не только, к примеру, для 1, а для 2, 2.5, 3 и т.д. То есть, нужно посчитать синусы списка чисел с помощью mapcar.
Помогите, пожалуйста, подправить программу. Для синуса от одного аргумента работает отлично, для всех остальных функций тоже.

Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
(defun F()
    (with-open-file (f1 "K:\\LISP\\LISP lb5\\funname.txt" :direction :input)
      (setq fun (read f1))
    )
    (with-open-file (f2 "K:\\LISP\\LISP lb5\\dataname.txt" :direction :input)
      (setq dan (read f2))
    )
 
(terpri)
(setq i 0)
(setq op 0)
(dolist (f fun)
        
        (cond 
            
 
            ((equal f 'abs)
            (princ "Результат функции abs: ")
            (princ (mapcar f (nth i dan)))(terpri)
            )           
                        ((equal f '-)
            (princ "Результат функции -: ")
            (princ (mapcar f (nth 0 (nth i dan)) (nth 1 (nth i dan))))(terpri)
            )
                ((equal f 'max)
            (princ "Результат функции max: ")
            (princ (mapcar f (nth 0 (nth i dan)) (nth 1 (nth i dan)) (nth 2 (nth i dan)) ))(terpri)
            )   
                        ((equal f 'apply)
            (princ "Результат функции apply: ")
                        (princ (mapcar f (nth 0 (nth i dan)) (nth 1 (nth i dan)) ))(terpri)
            )   
 
            )
    
            
 
    (setq i (+ i 1))
 
    )   
)
 
; (load "K:\\LISP\\LISP lb5\\5.lisp")   
; (F)
1
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.06.2014, 17:37
Ответы с готовыми решениями:

Mapcar
помогите пожалуйста, было задание вывести только положительные ключи ассоциативного списка, но моя...

Работа с mapcar
Привет всем! Помогите пожалуйста решить задачку, очень нужно: Используя функционал MAPCAR,...

Функция mapcar
Почему при вычислении данного выражения выводится ответ (10 10 10), а не (30 20 10)? Играет ли тут...

apply и mapcar
Объясните пожалуйста тупому человеку (т.е. мне) различие между mapcar и apply?????

Mapcar функции из файла
Написать программу ввода списка имен функций, ввода списка данных и получения списка результатов,...

11
ur_naz
Заблокирован
25.06.2014, 18:14 2
Во-первых, данные принято хранить в списках...
Lisp
1
2
3
4
(setq
  dat (load "data.lsp")
  fun (load "fun.lsp")
)
Дальше можно уже импровизировать:
Lisp
1
2
3
4
5
6
7
8
 (mapcar '(lambda (x)
   (princ (apply x dat)))
  fun
)
 (mapcar '(lambda (x)
   (princ (mapcar x dat)))
  fun
)
2
Argentum21
1 / 1 / 1
Регистрация: 05.03.2014
Сообщений: 75
25.06.2014, 19:06  [ТС] 3
Не то. Пишет, что lambda не аргумент для mapcar.
0
ur_naz
Заблокирован
25.06.2014, 19:17 4
Цитата Сообщение от Argentum21 Посмотреть сообщение
Пишет, что lambda не аргумент для mapcar.
Для начала следовало бы указать Ваш диалект лиспа...
0
25.06.2014, 19:17
Catstail
Модератор
24396 / 12334 / 2242
Регистрация: 12.02.2012
Сообщений: 20,037
25.06.2014, 20:53 5
Синус списка аргументов с помощью mapcar:

Lisp
1
2
3
4
5
6
7
8
(defun sin-l (lstx)
  (mapcar 'sin lstx))
 
==> sin-l
 
(sin-l '(1 2 3 4 5))
 
==> (0.841470984807897 0.909297426825682 0.141120008059867 -0.756802495307928 -0.958924274663138)
В чем проблема?

Добавлено через 17 минут
Заносим в один файл имена функций (или лямбда-выражения), в другой - списки аргументов (можно разной длины):

Файл "a-list.txt"

Код
1 2 3 4
0 2 1 0.3
1 2 3 4 5
Файл "f-list.txt"

Код
sin
cos
(lambda (x) (* x x))
Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
;; Решение
 
(defun task (flist alist)
  (let ((ff (gensym 'fi))
        (fa (gensym 'fi)))
    (filOpen ff flist _INPUT)
    (filOpen fa alist _INPUT)
    (loop
      (when (or (filEOF fa) (filEOF ff)) (return 'ok))
      (let ((args (input (strCat "(" (filGetLine fa) ")")))
            (func (input (filGetLine ff))))
           (print func) (printsline ":")
           (print args) (prints " -> ") (printline (mapcar func args))))  
    (filClose ff)
    (filClose fa)))
 
==> task
 
(task "f-list.txt" "a-list.txt")
 
SIN:
(1 2 3 4) -> (0.841470984807897 0.909297426825682 0.141120008059867 -0.756802495307928)
COS:
(0 2 1 0.3) -> (1.0 -0.416146836547142 0.54030230586814 0.955336489125606)
(LAMBDA (x) (* x x)):
(1 2 3 4 5) -> (1 4 9 16 25)
 
==> T
1
Argentum21
1 / 1 / 1
Регистрация: 05.03.2014
Сообщений: 75
25.06.2014, 21:13  [ТС] 6
Catstail, я новичок в Лиспе, поэтому Ваш код мне не слишком-то понятен.
Когда я заношу в файл (.txt) ( (sin) ((1)) ) - работает, но когда заношу ( (sin) (((1 2 3))) )-пишет, что (1 2 3) не является числом. В общем, я хотела бы, чтобы мне объяснили проблему именно в МОЕМ коде. Благодарю Вас.
0
ur_naz
Заблокирован
25.06.2014, 21:16 7
Цитата Сообщение от Argentum21 Посмотреть сообщение
Когда я заношу в файл (.txt) ( (sin) ((1)) ) - работает, но когда заношу ( (sin) (((1 2 3))) )-пишет, что (1 2 3) не является числом.
Заблудился в скобках? Посчитай сколько у тебя их в первом и втором варианте...
0
Catstail
Модератор
24396 / 12334 / 2242
Регистрация: 12.02.2012
Сообщений: 20,037
25.06.2014, 21:36 8
Цитата Сообщение от Argentum21 Посмотреть сообщение
Когда я заношу в файл (.txt) ( (sin) ((1)) ) - работает, но когда заношу ( (sin) (((1 2 3))) )-пишет, что (1 2 3) не является числом.
- так это действительно так! 1 - число, (1 2 3) - список.

Цитата Сообщение от Argentum21 Посмотреть сообщение
Список имен функций (файл .txt): (max - apply abs)
- это понятно.
Цитата Сообщение от Argentum21 Посмотреть сообщение
Список данных: (файл .txt): ( ((4) (7) (5)) ((4 2) (2 1)) ((sin) ( (1) )) (-100) )
- что в этом списке "делает" синус?
0
Argentum21
1 / 1 / 1
Регистрация: 05.03.2014
Сообщений: 75
25.06.2014, 21:41  [ТС] 9
Цитата Сообщение от Catstail Посмотреть сообщение
- что в этом списке "делает" синус?
((sin) ( (1) ))- список данных для функции apply
Но нужно получить значения синусов не только 1, а и каких-то других чисел
0
Catstail
Модератор
24396 / 12334 / 2242
Регистрация: 12.02.2012
Сообщений: 20,037
25.06.2014, 21:48 10
Цитата Сообщение от ur_naz Посмотреть сообщение
Для начала следовало бы указать Ваш диалект лиспа...
- в CommonLisp действительно нельзя писать так:

Lisp
1
(mapcar '(lambda (x) ...
Нужно так:

Lisp
1
(mapcar #'(lambda (x) ...
или просто:

Lisp
1
(mapcar (lambda (x) ...
Добавлено через 6 минут
А зачем столько скобок?

(max - apply abs) - список функций
((4 7 5) (4 2) (sin 1 2 3 4) (-100)) - список соотв. аргументов. Пойдет?

Соответствие:

max <-> (4 5 7)
- <-> (4 2)
apply <-> (sin 1 2 3 4)
abs <-> (-100)
0
Argentum21
1 / 1 / 1
Регистрация: 05.03.2014
Сообщений: 75
25.06.2014, 21:53  [ТС] 11
Добавлено через 41 секунду
Цитата Сообщение от Catstail Посмотреть сообщение
((4 7 5) (4 2) (sin 1 2 3 4) (-100)) - список соотв. аргументов. Пойдет?
Теперь ошибка такова: Истинный список не должен заканчиваться SIN
0
Catstail
Модератор
24396 / 12334 / 2242
Регистрация: 12.02.2012
Сообщений: 20,037
25.06.2014, 22:25 12
Да я и не предлагал сразу подавать новые списки в программу. Я спросил, зачем лишние скобки.

Добавлено через 20 минут
Давай разобьем задачу на две части: загрузка списков из файлов (1) и вычисление (2). И давай рассмотрим (2):

Lisp
1
2
3
4
5
6
7
8
;; применить каждую функцию списка func-list к соотв. элементу списка arg-list:
 
(defun exec (arg-list func-list)
  (mapcar #'(lambda (f arg) (apply f arg)) func-list arg-list)) 
 
(exec '((1 2 3) (5 8) (4 0.5) (-100)) '(max - + abs))
 
(3 -3 4.5 100) ;; все правильно
Можно и синус было сюда подставить. Но с одним аргументом:

Lisp
1
2
3
(exec '((1 2 3) (5 8) (4 0.5) (2.5)  (-100)) '(max - + sin  abs))
 
(3 -3 4.5 0.5984721 100) ;; все хорошо
Но если для синуса нужно вычислить не одно, а много значений, то для синуса придется "сделать исключение":

Lisp
1
2
3
4
5
6
7
8
(defun exec (arg-list func-list)
  (mapcar #'(lambda (f arg) (if (eq f 'sin) (mapcar 'sin arg) (apply f arg))) func-list arg-list)) 
 
;; и тогда:
 
(exec '((1 2 3) (5 8) (4 0.5) (1 2 3 4 5)  (-100)) '(max - + sin  abs))
 
(3 -3 4.5 (0.84147096 0.9092974 0.14112 -0.7568025 -0.9589243) 100) ;; !!!
1
25.06.2014, 22:25
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.06.2014, 22:25

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

Как сделать задачу применив функционал maplist или mapcar
Напишите функцию с использованием функционалов. При необходимости используйте локальные или...

Тема: функции высшего порядка (apply, funcall, mapcar, maplist)
(Common Lisp) Даны два списка x и y. Список y является упорядоченным по некоторому правилу....


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru