LINUX.ORG.RU

LIsp и массивы


0

0

Как в Lisp'e с идеологической и практической точки зрения заполнять массив ? Как быстрее всего (по времени) эффективней ? Циклы понятно - но это как-то не по-Lisp'овски. Если можно пример. Например a(i) = sin(i) - Цикл по i.

anonymous

все что написаное ниже, чисты бред пришедший мне в голову тока-что.
1) в лиспе есть массивы как таковые ваобше ?
2) в принцепе массив является часным случаем функции от одного аргумента.
3) заполнять если не циклами то рекурсивно, по другому помоему никак.
4) и ваобше нафига вам массив в лиспе, если идти из теории программирования, то там говорится что-то подобное несовместимости массивов и списков, всмысле юзать их вместе не есть гуд. а лисповская программа один большой список.

anonymous
()
Ответ на: комментарий от anonymous

> 1) в лиспе есть массивы как таковые ваобше ?

make-array ?

> 2) в принцепе массив является часным случаем функции от одного аргумента.

????

3) и 4)

Вот примерчик бы.

anonymous
()
Ответ на: комментарий от anonymous

>> 2) в принцепе массив является часным случаем функции от одного аргумента.

>????

Область определения - индексы массива, область значения - соотв. индексам значения ячеек массива.

seiken ★★★★★
()

REPL> (setq a (make-array 10))
#(NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL)

REPL> (dotimes (i 10) (setf (aref a i) (sin i)))
NIL

REPL> a
#(0 0.84147096 0.9092974 0.14112 -0.7568025 -0.9589243 -0.2794155 
0.6569866 0.98935825 0.4121185)

Zubok ★★★★★
()
Ответ на: комментарий от anonymous

Немножко не Common Lisp, а scheme, и я только начал учить, но всё же сделаю попытку-не-пытку =)

(define (sin-array n x dx) (if (> n 0) (cons (sin x) (sin-array (- n 1) (+ x dx) dx))))

n - количество элементов в массиве, x - начальное значение, dx - приращение.

Laz ★★★★★
()
Ответ на: комментарий от anonymous

Можно поиграться с параметром :initial-contents или с make-into.

Но цикл IMHO проще и нагляднее. И вполне в духе CL с его LOOP'ом.

(defparameter a (make-array 10))
(dotimes (i (length a))
   (setf (aref a i) (sin i)))

ЗЫ: Я не труЪ лиспер. :)

execve
()
Ответ на: комментарий от anonymous

>данных в CL рулят макросы.

да, они там человеские, да и не стоит забывать что в лиспе все это множества - а представить массив как множество ... :)

alphex_kaanoken ★★★
()

массивы нужны как упорядоченные наборы с доступом к произвольному
 элементу за время О(1). Т.е. для построения прог без них
 теоретически вполне можно обойтись, но с ними в некоторых
 редких случаях прога пишется легче и работает намного быстрее.
 Циклы - вполне кошерный и адекватный инструмент, будучи
 применяемы корректно. Например для инициализации массива.
 Рекурсивный же способ например таков:

(defun fill-array (a &optional (n 0))
  (when (array-in-bounds-p a n)
    (setf (aref a n) (sin n))
    (fill-array a (incf n))))

(defparameter a (make-array 10))
(fill-array a)

 Им можно пользоваться при желании но я не вижу никаких преимуществ
 перед dotimes в данном случае. Варианты с :initial-contents и map
 требуют чтобы значения, назначаемые элементам массива, были все
 уже вычислены на момент операции, а не вычислялись по ходу
 присвоения каждому элементу, так что это не всегда приемлемо.

bugmaker ★★★★☆
()
Ответ на: комментарий от bugmaker

А если тож самое, только для списков, т.е. создать список значений синуса, желательно dolist, ну или ещё как...

anonymous
()
Ответ на: комментарий от anonymous

То же самое что и для массива, только нужно использовать cons или push. dolist нужен чтобы перебирать уже готовый писок, так что он тут не при делах.

bugmaker ★★★★☆
()

Обработка полноценных массивов (допускающих запись и чтение значений) это всегда циклы в том или ином виде. Все остальные решения - syntactic sugar, который маскирует в себе цикл, с целью уберечь несформировавшуюся психику от жестокой правды жизни

Burbaka ★★
()
Ответ на: комментарий от Burbaka

Вот всё-таки со списками не выходит. Пытаюсь так:
(setf s (list 1))
(setf s (append s 1))
Первый раз проходит (1 . 1) получаю. А дальш е - ошибка. Что не так ? 

anonymous
()
Ответ на: комментарий от anonymous

append хавает на вход два списка, а ты ей подсовываешь список s и атомарное значение 1 

надо так 

(setf s (list 1))

(setf s (append s (list 1))

Cобственно глюки динамической типизации :) 

Burbaka ★★
()
Ответ на: комментарий от Burbaka

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

Burbaka ★★
()

Можно еще использовать iterate:

CL-USER> (require :iterate)
CL-USER> (use-package :iterate)
CL-USER> (iter (for i from 1 to 5)
	       (collect (sin i) result-type simple-vector))
#(0.84147096 0.9092974 0.14112 -0.7568025 -0.9589243)

Begemoth ★★★★★
()
Ответ на: комментарий от anonymous

[1]> (setq s nil)
NIL
[2]> (setq s (cons 1 s))
(1)
[3]> (setq s (cons 2 s))
(2 1)
[4]> (setq s (cons 3 s))
(3 2 1)

или так 

[1]> (setq s nil)
NIL
[2]> (push 1 s)
(1)
[3]> (push 2 s)
(2 1)
[4]> (push 3 s)
(3 2 1)
[5]> s
(3 2 1)

bugmaker ★★★★☆
()
Ответ на: комментарий от Burbaka

> append хавает на вход два списка, а ты ей подсовываешь
> список s и атомарное значение 1 

Нет, append appendид:

[1]> (setq s nil)
NIL
[2]> (setq s (append (list 1 2 3) s nil))
(1 2 3)
[3]> (setq s (append (list 4 5 6) s nil))
(4 5 6 1 2 3)

списки, а не точечные пары, в лиспе оканчиваются на nil.

bugmaker ★★★★☆
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.