近期在做一些练习的时候突然需要将一个列表排序,但是不能改变表中各原子的位置,写了下面一段代码,个人觉得太烦琐,希望各位大大能帮忙看下,或者有更简单的思路提供参考。
-
- ;;;计算一个整数序列表,获得一个列表,每项原子均代表的该原子在原列表中的排名
- ;;;例如: (Caldelta '(2 4 3 6 8 9 5 20 56))
- ;;;得到结果: (1 3 2 5 6 7 4 8 9)
- ;;;实际使用: 可以在一系列带序号的标注文字中删除某些标注文字,重新按照原来的大小
- ;;; 顺序排列这些序号,如'(1 3 5 7 9 2 4 6 8)这个列表中删除了(1 5 7)
- ;;; 得到新的序列 (3 9 2 4 6 8)
- ;;; 这时可以对这个序列重新排序
- ;;; 得到 (2 6 1 3 4 5)
- (defun CalDelta (numberlist / indexlist sortlist
- sortdelta len count countlist
- deltalist
- )
- (setq indexlist (vl-sort-i numberlist '<);_按从小到大的顺序求索引表
- sortlist (vl-sort numberlist '<);_按从小到大的顺序排序
- len (length numberlist);_表长度
- count 0
- )
- (repeat len
- (setq count (1+ count))
- (setq countlist (cons count countlist))
- );_构造列表(len...5 4 3 2 1)
- (setq countlist (reverse countlist));_倒序
- (setq sortdelta (mapcar '- sortlist countlist));_得到从小到大的顺序排序差值
- (setq deltalist (mapcar 'cons indexlist sortdelta));_构造索引表各元素和差值表的点对表
- (setq deltalist
- (vl-sort deltalist
- (function (lambda (e1 e2) (< (car e1) (car e2))));_点对表按照索引表顺序排列
- )
- )
- (setq deltalist (mapcar 'cdr deltalist));_得到差值表
- (mapcar '- numberlist deltalist)
- )
|