明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 3208|回复: 18

[讨论] 数组分类

  [复制链接]
发表于 2010-12-23 01:08 | 显示全部楼层 |阅读模式
请大侠帮忙 :将选择的数字进行分三组并自动编号A,B,C使A,B,C各组内的数字个数以及他们的和尽量平均  


本帖被以下淘专辑推荐:

 楼主| 发表于 2010-12-24 10:57 | 显示全部楼层
比如1,2,3,4,5,6,7
分为 1,2,7和 3,6 和4,5
每组的和为 10, 9,9 最接近
每组的个数为 3,2,2 最接近
发表于 2010-12-29 17:09 | 显示全部楼层
貌似下料优化。
 楼主| 发表于 2010-12-30 09:38 | 显示全部楼层
数学学的不好 不会
发表于 2010-12-30 10:36 | 显示全部楼层
回复 leeli 的帖子

看看这个程序行不行,大家讨论下!

  1. (defun gxl-lst-split (ls len / tmp rl i)
  2.   (setq i 0)
  3.   (foreach item ls
  4.     (setq tmp(append tmp(list item)))
  5.     (setq i(1+ i))
  6.     (if(zerop(rem i len))
  7.       (setq rl(cons tmp rl) tmp nil)
  8.     )
  9.   )
  10.   (if tmp (setq rl(cons tmp rl) tmp nil))
  11.   (reverse rl)
  12. )
  13. (defun gxl-sort (lst func)
  14.   (setq lst-i (VL-SORT-I lst func))
  15.   (mapcar '(lambda (x) (nth x lst)) lst-i)
  16.   
  17.   )
  18. ;;; (averagelst '(1 2 3 2 5 4 5 6 7 7))
  19. (defun averagelst (lst / lst1  lst2 lst3 lst4 rtn i )
  20.   ;;;表从小到大排序
  21.   (setq lst1 (gxl-sort lst '(lambda (e1 e2) (< e1 e2))))
  22.   
  23.   ;;;表长度如不是3的倍数,拆分为两个表lst1 和lst2
  24.   (if (= 1 (rem (length lst1) 3))
  25.     (setq lst2 (list (car lst1))
  26.           lst1 (cdr lst1)
  27.           )
  28.     (if (= 2 (rem (length lst1) 3))
  29.       (setq lst2 (reverse (list (car lst1) (cadr lst1)))
  30.             lst1 (cddr lst1)
  31.             )
  32.       )
  33.     )
  34.   ;;;表lst1 拆分长度为3 的表
  35.   (setq lst1 (GXL-LST-SPLIT lst1 3))
  36.   
  37.   (setq i -1)
  38.   ;;;各组数据按奇偶位置的不同进行大小反序
  39.   (setq lst1 (mapcar '(lambda (x) (if (= (rem (setq i (1+ i)) 2) 1) (reverse x) x)) lst1))
  40.   (if (= 0 (rem (length lst1) 2))
  41.     ;;;lst1表个数为偶数,依次组表
  42.     (setq rtn (apply 'mapcar (cons 'list lst1)))
  43.     ;;;lst1表个数为奇数,取出第一个表,剩下的依次组表
  44.     (progn
  45.       (setq lst3 (car lst1)
  46.             lst1 (cdr lst1)
  47.             )
  48.       ;;;取出第一个表,剩下的依次组表
  49.       (setq rtn (apply 'mapcar (cons 'list lst1)))
  50.       ;;;按各组数据的和从小到大排序
  51.       (setq rtn (GXL-SORT rtn '(lambda (e1 e2) (< (apply '+ e1) (apply '+ e2)))))
  52.       ;;;取出第的一个表从大到小排序
  53.       (setq lst3 (GXL-SORT lst3 '(lambda (e1 e2) (> e1 e2))))
  54.       ;;;将lst3加入组表
  55.       (setq rtn (mapcar 'cons lst3 rtn))
  56.       )
  57.     )
  58.   ;;;按各组数据的和从小到大排序
  59.   (setq rtn (gxl-sort rtn '(lambda (e1 e2) (< (apply '+ e1) (apply '+ e2)))))
  60.   ;;;对剩余lst2表组表
  61.   (if lst2
  62.     (if (= 1 (length lst2))
  63.       (setq rtn (cons (cons (car lst2) (car rtn)) (cdr rtn)))
  64.       (if (= 2 (length lst2))
  65.         (setq lst4 (car rtn)
  66.               lst5 (cadr rtn)
  67.               rtn (cddr rtn)
  68.               lst4 (cons (car lst2) lst4)
  69.               lst5 (cons (cadr lst2) lst5)
  70.               rtn (append (list lst4 lst5) rtn)
  71.               )
  72.         )
  73.        
  74.       
  75.       )
  76.     )
  77.   rtn
  78.   )

发表于 2010-12-30 11:37 | 显示全部楼层
也 研究研究
发表于 2010-12-31 00:23 | 显示全部楼层
本帖最后由 Gu_xl 于 2010-12-31 08:06 编辑

修正一下,当表长小于6个时的错误!请大家测试
  1. ;;; (averagelst '(1 2 3  5 10 5 6 8 3 12)) 返回 '((1 3 6 8) (3 5 10) (2 5 12)) (setq lst '(1 2 3  5 10 5 6 8 3 12))
  2. (defun averagelst (lst / lst1  lst2 lst3 lst4 rtn i )
  3.   ;;;表从小到大排序
  4.   (setq lst1 (gxl-sort lst '(lambda (e1 e2) (> e1 e2))))
  5.   (if (< (length lst1) 4)
  6.     (setq rtn (reverse (mapcar 'list lst1)))
  7.       
  8.       (progn

  9.   ;;;表lst1 拆分长度为3 的表
  10.   (setq lst1 (reverse (GXL-LST-SPLIT lst1 3)))
  11.   ;;;表长度如不是3的倍数,拆分为两个表lst1 和lst2
  12.   (if (/= 3 (length (car lst1)))
  13.     (setq lst2 (reverse (car lst1))
  14.    lst1 (mapcar 'reverse (cdr lst1))
  15.    )
  16.     )
  17.   (setq i -1)
  18.   ;;;各组数据按奇偶位置的不同进行大小反序
  19.   (setq lst1 (mapcar '(lambda (x) (if (= (rem (setq i (1+ i)) 2) 1) (reverse x) x)) lst1))
  20.   (if (= 0 (rem (length lst1) 2))
  21.     ;;;lst1表个数为偶数,依次组表
  22.     (setq rtn (apply 'mapcar (cons 'list lst1)))
  23.     ;;;lst1表个数为奇数,取出第一个表,剩下的依次组表
  24.     (progn
  25.       (if (/= (length lst1) 1)

  26.       (setq lst3 (car lst1)
  27.             lst1 (cdr lst1)
  28.             )
  29. )
  30.       ;;;取出第一个表,剩下的依次组表
  31.       (setq rtn (apply 'mapcar (cons 'list lst1)))
  32.       ;;;按各组数据的和从小到大排序
  33.       (setq rtn (GXL-SORT rtn '(lambda (e1 e2) (< (apply '+ e1) (apply '+ e2)))))
  34.       (if lst3
  35. (progn
  36.       ;;;取出第的一个表从大到小排序
  37.       (setq lst3 (GXL-SORT lst3 '(lambda (e1 e2) (> e1 e2))))
  38.       ;;;将lst3加入组表
  39.       (setq rtn (mapcar 'cons lst3 rtn))
  40.       )
  41. )
  42.       )
  43.     )
  44.   ;;;按各组数据的和从小到大排序
  45.   (setq rtn (gxl-sort rtn '(lambda (e1 e2) (< (apply '+ e1) (apply '+ e2)))))
  46.   ;;;对剩余lst2表组表
  47.   (if lst2
  48.     (if (= 1 (length lst2))
  49.       (setq rtn (cons (cons (car lst2) (car rtn)) (cdr rtn)))
  50.       (if (= 2 (length lst2))
  51.         (setq lst4 (car rtn)
  52.               lst5 (cadr rtn)
  53.               rtn (cddr rtn)
  54.               lst4 (cons (car lst2) lst4)
  55.               lst5 (cons (cadr lst2) lst5)
  56.               rtn (append (list lst4 lst5) rtn)
  57.               )
  58.         )
  59.         
  60.       
  61.       )
  62.     )
  63.     )
  64.     )
  65.   rtn
  66.   )

点评

弱弱请问版主:这种“(defun averagelst ”,没有 c: 的语句,如何运行,命令是什么? 我试试学习操作一下,提示:; 错误: 参数太少 请指教。 谢谢  发表于 2011-1-2 21:00
 楼主| 发表于 2011-1-1 23:51 | 显示全部楼层
GXL-SORT不懂是什么
在研究
发表于 2011-1-2 00:02 | 显示全部楼层
回复 leeli 的帖子

GXL-SORT是替代vl-sort的函数,因为使用vl-sort函数排序,该函数的返回值可能删除了相同值的元素!例如
(vl-sort '(1 2 3 2 4 6 4 7) '(lambda (e1 e2) (< e1 e2)))
返回 '(1 2 3 4 6 7)
而使用GXL-SORT函数则不会删除相同值的原素,(gxl-sort '(1 2 3 2 4 6 4 7) '(lambda (e1 e2) (< e1 e2)))
返回
'(1 2 2 3 4 4 6 7)
 楼主| 发表于 2011-1-21 23:51 | 显示全部楼层
谢谢 领导解释
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-5-9 06:01 , Processed in 0.348618 second(s), 33 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表